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事务的隔离级别与MVCC
Apr 22 MySQL
MYSQL数据库使用UTF-8中文编码乱码的解决办法
May 26 MySQL
Mysql中存储引擎的区别及比较
Jun 04 MySQL
MySQL索引失效的典型案例
Jun 05 MySQL
MySQL去除重叠时间求时间差和的实现
Aug 23 MySQL
MySQL分区表实现按月份归类
Nov 01 MySQL
mysql分组后合并显示一个字段的多条数据方式
Jan 22 MySQL
MySQL三种方式实现递归查询
Apr 18 MySQL
MySQL查询日期时间
May 15 MySQL
MySQL主从切换的超详细步骤
Jun 28 MySQL
数据设计之权限的实现
Aug 05 MySQL
了解MySQL查询语句执行过程(5大组件)
Aug 14 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
Javascript执行效率全面总结
2013/11/04 Javascript
JavaScript判断变量是对象还是数组的方法
2014/08/28 Javascript
JavaScript中获取样式的原生方法小结
2014/10/08 Javascript
JavaScript中的关联数组问题
2015/03/04 Javascript
js拆分字符串并将分割的数据放到数组中的方法
2015/05/06 Javascript
跟我学习javascript的undefined与null
2015/11/17 Javascript
JavaScript中eval()函数用法详解
2015/12/14 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
2016/06/12 Javascript
微信小程序 教程之事件
2016/10/18 Javascript
微信小程序开发(二)图片上传+服务端接收详解
2017/01/11 Javascript
JS实现仿UC浏览器前进后退效果的实例代码
2017/07/17 Javascript
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
2018/07/30 Javascript
小程序组件之仿微信通讯录的实现代码
2018/09/12 Javascript
基于vue开发微信小程序mpvue-docs跳转页面功能
2019/04/10 Javascript
javascript实现弹幕墙效果
2019/11/28 Javascript
jQuery操作元素的内容和样式完整实例分析
2020/01/10 jQuery
js实现微信聊天界面
2020/08/09 Javascript
[01:28]国服启动器接入蒸汽平台操作流程视频
2021/03/11 DOTA
django小技巧之html模板中调用对象属性或对象的方法
2018/11/30 Python
Django后台admin的使用详解
2019/07/08 Python
python进程的状态、创建及使用方法详解
2019/12/06 Python
Python之Django自动实现html代码(下拉框,数据选择)
2020/03/13 Python
用python写一个带有gui界面的密码生成器
2020/11/06 Python
如何用Python和JS实现的Web SSH工具
2021/02/23 Python
HTML5资源预加载(Link prefetch)详细介绍(给你的网页加速)
2014/05/07 HTML / CSS
MAC Cosmetics巴西官方网站:M·A·C彩妆
2019/04/18 全球购物
Blank NYC官网:夹克、牛仔裤等
2020/12/16 全球购物
介绍java中初始化块的使用
2012/09/11 面试题
是否可以从一个static方法内部发出对非static方法的调用?
2014/08/18 面试题
J2EE面试题
2016/03/14 面试题
木工主管岗位职责
2013/12/08 职场文书
离职证明范本(5篇)
2014/09/19 职场文书
中小学校园安全广播稿
2014/09/29 职场文书
员工工作能力评语
2014/12/31 职场文书
高一化学教学反思
2016/02/22 职场文书
Python控制台输出俄罗斯方块移动和旋转功能
2021/04/18 Python