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 COUNT函数的使用与优化
May 10 MySQL
MySQL如何构建数据表索引
May 13 MySQL
虚拟机linux端mysql数据库无法远程访问的解决办法
May 26 MySQL
Mysql数据库按时间点恢复实战记录
Jun 30 MySQL
详细聊聊关于Mysql联合查询的那些事儿
Oct 24 MySQL
MySQL 开窗函数
Feb 15 MySQL
教你如何让spark sql写mysql的时候支持update操作
Feb 15 MySQL
一条 SQL 语句执行过程
Mar 17 MySQL
mysql 体系结构和存储引擎介绍
May 06 MySQL
MySQL sql模式设置引起的问题
May 15 MySQL
MySQL数据库实验实现简单数据库应用系统设计
Jun 21 MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
Jul 15 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边学边教》(04.编写简易的通讯录――视频教程1)
2006/12/13 PHP
利用PHP制作简单的内容采集器的代码
2007/11/28 PHP
ZF等常用php框架中存在的问题
2008/01/10 PHP
PHP获取数组的键与值方法小结
2015/06/13 PHP
在JavaScript中通过URL传递汉字的方法
2007/04/09 Javascript
JS实现div内部的文字或图片自动循环滚动代码
2013/04/19 Javascript
js获取select标签的值且兼容IE与firefox
2013/12/30 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
js与jquery实时监听输入框值的oninput与onpropertychange方法
2015/02/05 Javascript
浅谈javascript基础之客户端事件驱动
2016/06/10 Javascript
详解webpack+vue-cli项目打包技巧
2017/06/17 Javascript
vue-router实现tab标签页(单页面)详解
2017/10/17 Javascript
使用 Node.js 开发资讯爬虫流程
2018/01/07 Javascript
「中高级前端面试」JavaScript手写代码无敌秘籍(推荐)
2019/04/08 Javascript
VUE前后端学习tab写法实例
2019/08/06 Javascript
js实现简单的点名器随机色实例代码
2020/09/20 Javascript
[01:08:09]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第二局
2016/03/02 DOTA
Python ORM编程基础示例
2020/02/02 Python
浅析python标准库中的glob
2020/03/13 Python
Python 合并拼接字符串的方法
2020/07/28 Python
python 实现非极大值抑制算法(Non-maximum suppression, NMS)
2020/10/15 Python
德国网上宠物店:Zoobio
2018/05/23 全球购物
Ivory Isle Designs美国/加拿大:婚礼和活动文具公司
2018/08/21 全球购物
PHP开发工程师面试问题集锦
2012/11/01 面试题
下面这个程序执行后会有什么错误或者效果
2014/11/03 面试题
高级护理专业毕业生推荐信
2013/12/25 职场文书
校园报刊亭的创业计划书
2014/01/02 职场文书
开业主持词
2014/03/21 职场文书
大学共青团员个人自我评价
2014/04/16 职场文书
环境科学专业教师求职信
2014/07/12 职场文书
师德先进个人材料
2014/12/20 职场文书
CSS实现多个元素在盒子内两端对齐效果
2021/03/30 HTML / CSS
HTML+CSS+JS实现图片的瀑布流布局的示例代码
2021/04/22 HTML / CSS
超详细Python解释器新手安装教程
2021/05/10 Python
python库sklearn常用操作
2021/08/23 Python
Redis调用Lua脚本及使用场景快速掌握
2022/03/16 Redis