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之DML语言
Apr 05 MySQL
MySQL kill不掉线程的原因
May 07 MySQL
解读MySQL的客户端和服务端协议
May 10 MySQL
分析MySQL抛出异常的几种常见解决方式
May 18 MySQL
MySQL 存储过程的优缺点分析
May 20 MySQL
浅谈mysql增加索引不生效的几种情况
Jun 23 MySQL
QT连接MYSQL数据库的详细步骤
Jul 07 MySQL
MySQL中连接查询和子查询的问题
Sep 04 MySQL
MySQL之select、distinct、limit的使用
Nov 11 MySQL
关于k8s环境部署mysql主从的问题
Mar 13 MySQL
MySQL分区路径子分区再分区
Apr 13 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中取得URL的根域名的代码
2011/03/23 PHP
PHP函数分享之curl方式取得数据、模拟登陆、POST数据
2014/06/04 PHP
PHP基于迭代实现文件夹复制、删除、查看大小等操作的方法
2017/08/11 PHP
传递参数的标准方法(jQuery.ajax)
2008/11/19 Javascript
JavaScript中的console.trace()函数介绍
2014/12/29 Javascript
JavaScript匿名函数用法分析
2015/02/13 Javascript
EasyUI实现二级页面的内容勾选的方法
2015/03/01 Javascript
Jquery判断radio、selelct、checkbox是否选中及获取选中值方法总结
2015/04/15 Javascript
Javascript基础学习笔记(菜鸟必看篇)
2016/07/22 Javascript
JS实现保留n位小数的四舍五入问题示例
2016/08/03 Javascript
JS数字千分位格式化实现方法总结
2016/12/16 Javascript
jquery获取select,option所有的value和text的实例
2017/03/06 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
2017/06/11 Javascript
JavaScript实现百度搜索框效果
2020/03/26 Javascript
Vue 配合eiement动态路由,权限验证的方法
2018/09/26 Javascript
vue实现中部导航栏布局功能
2019/07/30 Javascript
JS严格模式原理与用法实例分析
2020/04/27 Javascript
[00:35]DOTA2上海特级锦标赛 Newbee战队宣传片
2016/03/03 DOTA
[01:08]DOTA2“血战之命”预告片
2017/08/12 DOTA
[01:10:30]DOTA2-DPC中国联赛正赛 Dragon vs Dynasty BO3 第一场 3月4日
2021/03/11 DOTA
详细讲解Python中的文件I/O操作
2015/05/24 Python
python实现windows壁纸定期更换功能
2019/01/21 Python
python Jupyter运行时间实例过程解析
2019/12/13 Python
python 命名规范知识点汇总
2020/02/14 Python
CSS3实现内凹圆角的实例代码
2017/05/04 HTML / CSS
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
美国经典刺绣和字母儿童服装特卖:Smocked Auctions
2018/07/16 全球购物
波兰在线儿童和婴儿用品零售商:pinkorblue
2019/06/29 全球购物
Shop Apotheke瑞士:您的健康与美容网上商店
2019/10/09 全球购物
系统管理员的职责包括那些?管理的对象是什么?
2013/01/18 面试题
安全员岗位职责
2013/11/11 职场文书
审计专业自荐信范文
2014/04/21 职场文书
广播节目策划方案
2014/05/23 职场文书
2014年导购员工作总结
2014/11/18 职场文书
餐厅如何利用“营销策略”扭转亏本局面
2019/10/15 职场文书
Python游戏开发实例之graphics实现AI五子棋
2021/11/01 Python