MySQL常见优化方案汇总


Posted in MySQL onJanuary 18, 2022

mysql优化是我们日常工作经常遇到的问题,今天给大家说下MySQL常见的几种优化方案。

注:原始资料来自享学课堂,自己加上整理和思考

思考sql优化的几个地方,我把他做了个分类,方便理解

select [字段 优化1]:主要是覆盖索引
from []
where [条件 优化2]
union [联合查询 优化3]
新建表格

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(50) DEFAULT NULL COMMENT '姓名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `phone` varchar(12) DEFAULT NULL,
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

添加索引,添加索引之后

key_len:根据这个值,就可以判断索引使用情况,特别是在组合索引的时候,判断所有的索引字段是否都被查询用到。

key_len计算方式简单介绍

latin1占用1个字节,gbk占用2个字节,utf8占用3个字节

不允许为空:

varchar(10):10*3

char(10):10*3+2

int:4

允许为空:

varchar(10):10*3+1

char(10):10*3+2+1

int:4+1

使用完全索引key_len=name(50*3+2+1=153)+age(4+1)+phone(12*3+2+1=39)

alter table studen add index name_age_phone(name, age, phone);

添加数据

insert into student(name,age,phone,create_time) values('赛文',1000,'15717177664',now());
insert into student(name,age,phone,create_time) values('雷欧',1200,'15733337664',now());
insert into student(name,age,phone,create_time) values('泰罗',800,'15714447664',now());

一、优化点1:字段优化

覆盖索引尽量用

简单解释解释,索引是哪几个列,就查询哪几个列: 覆盖索引的原因:索引是高效找到行的一个方法,但是一般数据库也能使用 索引找到一个列的数据,因此它 不必读取整个行。毕竟索引叶子节点存储了它们索引的数据; 当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引 包含了(或 覆盖了)满足查询结果的数据就叫做覆盖索引 注意:有索引尽量不要使用select *

#未覆盖索引
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';
#覆盖了索引
EXPLAIN SELECT name,age,phone FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';
#包含了索引
EXPLAIN SELECT name FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';
#加上主键也还是覆盖索引
EXPLAIN SELECT id, name,age,phone FROM student WHERE NAME = '泰罗' and age =1000 and phone='15717177664';

未使用覆盖索引

MySQL常见优化方案汇总

使用完全覆盖索引

MySQL常见优化方案汇总

使用包含覆盖索引

MySQL常见优化方案汇总

加上主键还是覆盖索引

MySQL常见优化方案汇总

二、优化点2:where优化

1.尽量全值匹配

EXPLAIN SELECT * FROM student WHERE NAME = '赛文';
EXPLAIN SELECT * FROM student WHERE NAME = '雷欧' AND age = 1200;
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' AND age = 800 AND phone = '15714447664';

执行结果,三个都用到了索引,但是key_len是不同的,key_len=197,表示所有索引都使用到了

MySQL常见优化方案汇总

当建立了索引列后,能在 wherel 条件中使用索引的尽量所用。

2.最佳左前缀法则

最左前缀法则:指的是查询从索引的最左前列开始并且不跳过索引中的列。 我们定义的索引顺序是 name_age_phone ,所以查询的时候也应该从name开始,然后age,然后phone 情况1:从age、phone开始查询,tpye=All,key = null,没使用索引

MySQL常见优化方案汇总

情况2:从phone开始查询,type=All,key=null,未使用索引

MySQL常见优化方案汇总

情况3:从name开始,type=ref,使用了索引

MySQL常见优化方案汇总

3.范围条件放最后

没有使用范围查询,key_len=197,使用到了name+age+phone组合索引

EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' AND age = 1000 AND phone = '15717177664';

MySQL常见优化方案汇总

使用了范围查询,key_len从197变为158,即除了name和age,phone索引失效了

EXPLAIN SELECT * FROM student WHERE NAME = '泰罗' AND age > 800 AND phone = '15717177664';

key_len=name(153)+age(5)

MySQL常见优化方案汇总

4.不在索引列上做任何操作

EXPLAIN SELECT * FROM student WHERE NAME = '泰罗';
EXPLAIN SELECT * FROM student WHERE left(NAME,1) = '泰罗';

不做计算,key_len有值,key_len=153,有使用name索引

MySQL常见优化方案汇总

做了截取结算,type=All,key_len=null,未使用索引

MySQL常见优化方案汇总

5.不等于要甚用

mysql 在使用不等于 (!= 或者 <>) 的时候无法使用索引会导致全表扫描

#有使用到索引
EXPLAIN SELECT * FROM student WHERE NAME = '泰罗';
#不等于查询,未使用到索引
EXPLAIN SELECT * FROM student WHERE NAME != '泰罗';
EXPLAIN SELECT * FROM student WHERE NAME <> '泰罗';
 
#如果定要需要使用不等于,请用覆盖索引
EXPLAIN SELECT name,age,phone FROM student WHERE NAME != '泰罗';
EXPLAIN SELECT name,age,phone FROM student WHERE NAME <> '泰罗';

使用不等于查询,跳过索引

MySQL常见优化方案汇总

使用不等于查询,同时使用覆盖索引,此时可以使用到索引

MySQL常见优化方案汇总

6.Null/Not null有影响

修改为非空

MySQL常见优化方案汇总

那么为not null,此时导致索引失效

EXPLAIN select * from student where name is null;
EXPLAIN select * from student where name is not null;

MySQL常见优化方案汇总

MySQL常见优化方案汇总

改为可以为空

MySQL常见优化方案汇总

查询为空,索引起作用了

MySQL常见优化方案汇总

查询非空索引失效

MySQL常见优化方案汇总

解决方法:

使用覆盖索引(覆盖索引解千愁)

MySQL常见优化方案汇总

7、Like 查询要当心 like

以通配符开头 ('%abc...')mysql 索引失效会变成全表扫描的操作

#like 以通配符开头('%abc...')mysql 索引失效会变成全表扫描的操作
#索引有效
EXPLAIN select * from student where name ='泰罗';
#索引失效
EXPLAIN select * from student where name like '%泰罗%';
#索引失效
EXPLAIN select * from student where name like '%泰罗';
#索引有效
EXPLAIN select * from student where name like '泰罗%';
 
解决方式:覆盖索引
EXPLAIN select name,age,phone from student where name like '%泰罗%';

MySQL常见优化方案汇总

MySQL常见优化方案汇总

MySQL常见优化方案汇总

MySQL常见优化方案汇总

使用覆盖索引能够解决

MySQL常见优化方案汇总

8.字符类型加引号

字符串不加单引号索引失效(这个看着有点鸡肋了,一般查询字符串都会加上引号)

MySQL常见优化方案汇总

使用覆盖索引解决

MySQL常见优化方案汇总

三、优化3

1.OR 改 UNION 效率高

未使用索引
EXPLAIN select * from student where name='泰罗' or name = '雷欧';
 
使用索引
EXPLAIN
select * from student where name='泰罗'
UNION
select * from student where name = '雷欧';
 
解决方式:覆盖索引
EXPLAIN select name,age from student where name='泰罗' or name = '雷欧';

使用or未使用到索引

MySQL常见优化方案汇总

使用union,使用了索引

MySQL常见优化方案汇总

解决方式:覆盖索引

MySQL常见优化方案汇总

到此这篇关于MySQL常见优化方案汇总的文章就介绍到这了,更多相关MySQL优化方案内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
Mysql - 常用函数 每天积极向上
Apr 05 MySQL
MySQL 角色(role)功能介绍
Apr 24 MySQL
JDBC连接的六步实例代码(与mysql连接)
May 12 MySQL
MySQL 如何分析查询性能
May 12 MySQL
简单了解 MySQL 中相关的锁
May 25 MySQL
mysql优化之query_cache_limit参数说明
Jul 01 MySQL
MySQL分库分表详情
Sep 25 MySQL
MySQL表类型 存储引擎 的选择
Nov 11 MySQL
浅谈redis的过期时间设置和过期删除机制
Mar 18 MySQL
实战 快速定位MySQL的慢SQL
Mar 22 MySQL
CentOS 7安装mysql5.7使用XtraBackUp备份工具命令详解
Apr 12 MySQL
MySQL索引 高效获取数据的数据结构
May 02 MySQL
mysql sum(if())和count(if())的用法说明
SQL语法CONSTRAINT约束操作详情
Jan 18 #MySQL
MySQL笔记 —SQL运算符
Jan 18 #MySQL
Mysql中一千万条数据怎么快速查询
Dec 06 #MySQL
Mysql中有关Datetime和Timestamp的使用总结
Dec 06 #MySQL
详解MySQL中timestamp和datetime时区问题导致做DTS遇到的坑
Dec 06 #MySQL
mysql中整数数据类型tinyint详解
Dec 06 #MySQL
You might like
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
迅速确定php多维数组的深度的方法
2014/01/07 PHP
PHP向浏览器输出内容的4个函数总结
2014/11/17 PHP
php中try catch捕获异常实例详解
2014/11/21 PHP
php限制ip地址范围的方法
2015/03/31 PHP
PHP查找一列有序数组是否包含某值的方法
2020/02/07 PHP
基于Web标准的UI组件 — 树状菜单(2)
2006/09/18 Javascript
JS判断是否为数字,是否为整数,是否为浮点数的代码
2010/04/24 Javascript
一次失败的jQuery优化尝试小结
2011/02/06 Javascript
cument.execCommand()用法深入理解
2012/12/04 Javascript
jquery 提示信息显示后自动消失的具体实现
2013/12/18 Javascript
JS获取文本框,下拉框,单选框的值的简单实例
2014/02/26 Javascript
javascript进行数组追加方法小结
2014/06/16 Javascript
Python脚本后台运行的几种方式
2015/03/09 Javascript
jQuery Easyui学习之datagrid 动态添加、移除editor
2016/01/27 Javascript
JQuery EasyUI的使用
2016/02/24 Javascript
JavaScript是如何实现继承的(六种方式)
2016/03/31 Javascript
javascript制作照片墙及制作过程中出现的问题
2016/04/04 Javascript
深入理解jQuery事件绑定
2016/06/02 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
Vue内容分发slot(全面解析)
2017/08/19 Javascript
Javascript中将变量转换为字符串的三种方法
2017/09/19 Javascript
实用Javascript调试技巧分享(小结)
2019/06/18 Javascript
详解element-ui表格中勾选checkbox,高亮当前行
2019/09/02 Javascript
小程序跳转H5页面的方法步骤
2020/03/06 Javascript
Python的for和break循环结构中使用else语句的技巧
2016/05/24 Python
Python中json格式数据的编码与解码方法详解
2016/07/01 Python
详解Python的数据库操作(pymysql)
2019/04/04 Python
python TF-IDF算法实现文本关键词提取
2019/05/29 Python
python中的函数递归和迭代原理解析
2019/11/14 Python
Python selenium爬取微博数据代码实例
2020/05/22 Python
利用Python函数实现一个万历表完整示例
2021/01/23 Python
小学生打架检讨书
2014/01/26 职场文书
总经理秘书岗位职责
2014/03/17 职场文书
奉献演讲稿范文
2014/05/21 职场文书
uniapp引入支付宝原生扫码插件步骤详解
2022/07/23 Javascript