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 08 MySQL
MySQL主从搭建(多主一从)的实现思路与步骤
May 13 MySQL
MySQL 存储过程的优缺点分析
May 20 MySQL
MySQL5.7并行复制原理及实现
Jun 03 MySQL
MySql 缓存查询原理与缓存监控和索引监控介绍
Jul 02 MySQL
MySQL千万级数据表的优化实战记录
Aug 04 MySQL
Mysql实现简易版搜索引擎的示例代码
Aug 30 MySQL
MySQL实例精讲单行函数以及字符数学日期流程控制
Oct 15 MySQL
浅谈mysql哪些情况会导致索引失效
Nov 20 MySQL
MySQL 条件查询的常用操作
Apr 28 MySQL
MySQL示例讲解数据库约束以及表的设计
Jun 16 MySQL
delete in子查询不走索引问题分析
Jul 07 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
yii上传文件或图片实例
2014/04/01 PHP
微信公众号开发客服接口实例代码
2016/10/21 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
2021/03/09 PHP
JS 页面自动加载函数(兼容多浏览器)
2009/05/18 Javascript
JS+XML 省份和城市之间的联动实现代码
2009/10/14 Javascript
基于jquery的一个浮动框(扩展性比较好 )
2010/08/27 Javascript
如何确保JavaScript的执行顺序 之实战篇
2011/03/03 Javascript
实现变速回到顶部的JavaScript代码
2011/05/09 Javascript
深入理解Javascript动态方法调用与参数修改的问题
2013/12/10 Javascript
javascript简单性能问题及学习笔记
2014/02/04 Javascript
详解easyui基于 layui.laydate日期扩展组件
2018/07/18 Javascript
JQuery事件委托原理与用法实例分析
2019/05/13 jQuery
nestjs中异常过滤器Exceptionfilter的具体使用
2021/02/07 Javascript
[01:02]2014 DOTA2国际邀请赛中国区预选赛 现场抢先看
2014/05/22 DOTA
用Python编程实现语音控制电脑
2014/04/01 Python
pygame学习笔记(4):声音控制
2015/04/15 Python
python如何实现反向迭代
2018/03/20 Python
python 读取文本文件的行数据,文件.splitlines()的方法
2018/07/12 Python
python 实现求解字符串集的最长公共前缀方法
2018/07/20 Python
python中将正则过滤的内容输出写入到文件中的实例
2018/10/21 Python
python实现给scatter设置颜色渐变条colorbar的方法
2018/12/13 Python
使用virtualenv创建Python环境及PyQT5环境配置的方法
2019/09/10 Python
python实现梯度下降和逻辑回归
2020/03/24 Python
Python调用ffmpeg开源视频处理库,批量处理视频
2020/11/16 Python
利用CSS3的定位页面元素
2009/08/29 HTML / CSS
Artist Guitars新西兰:乐器在线商店
2017/09/17 全球购物
Java TransactionAPI (JTA) 主要包含几部分
2012/12/07 面试题
介绍一下except的用法和作用
2015/01/22 面试题
西式婚礼证婚词
2014/01/12 职场文书
警察先进个人事迹材料
2014/05/16 职场文书
户籍证明格式
2014/09/15 职场文书
教师工作表现自我评价
2015/03/05 职场文书
幼儿园奖惩制度范本
2015/08/05 职场文书
学习习近平主席讲话心得体会
2016/01/20 职场文书
立秋之描写立秋的作文(五年级)
2019/08/08 职场文书
Golang 入门 之url 包
2022/05/04 Golang