SQL调优带您涨薪资-explian分析SQL执行计划并优化

Posted 栗子~~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL调优带您涨薪资-explian分析SQL执行计划并优化相关的知识,希望对你有一定的参考价值。

文章目录

前言

  如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。
  而且听说点赞的人每天的运气都不会太差,实在白嫖的话,那欢迎常来啊!!!


SQL调优带您涨薪资-explian分析SQL执行计划并优化

01 前期准备

CREATE TABLE `test` (
  `id` bigint(200) NOT NULL AUTO_INCREMENT,
  `age` varchar(200) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index_test` (`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4;

INSERT INTO `testdb`.`test`(`id`, `age`, `name`) VALUES (1, '21', 'noTransactional');
INSERT INTO `testdb`.`test`(`id`, `age`, `name`) VALUES (2, '21', 'noTransactional');
INSERT INTO `testdb`.`test`(`id`, `age`, `name`) VALUES (3, '9879', 'noTransactional');
INSERT INTO `testdb`.`test`(`id`, `age`, `name`) VALUES (4, '24332', 'noTransactional');

CREATE TABLE `test_version` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `version` varchar(50) DEFAULT NULL COMMENT '版本号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

INSERT INTO `testdb`.`test_version`(`id`, `version`) VALUES (1, '1');

实例:

explain select * from test where id = (SELECT p.id from test_version o left join test p on o.id = p.id and p.id in(SELECT id from test) and p.id = ‘1’);


02 explain 字段含义

序号字段含义
1idselect的查询序列号
2select_typeselect的类型,主要包含(SIMPLE ,PRIMARY,SUBQUERY, DERIVED ,UNION ,UNION RESULT)
3table输出结果的表
4partitions
5type显示连接使用了那种类型(all,index,range,ref,eq_ref,consf,system,null)
6possible_keys指出mysql能使用哪个索引在该表中找到
7key显示mysql 实际决定使用哪个键(索引),如果没有选择索引,键是NULL
8key_len显示mysql实际决定使用的键长度,如果键是null,则长度为null,使用索引的长度在不损失精度的前提下,长度越短越好。
9ref显示索引的那一列被使用了
10rows显示mysql认为执行查询时要检查的行数
11filtered返回结果的行占需要读到的行(rows列的值)的百分比,越大越好
12extra包含不适合在其他列中显式但十分重要的额外信息

03 分析SQL的执行计划瓶颈的关键项:

03::01 id

  • id相同 执行顺序由上到下;

  • id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行;

  • id即有相同的也有不同的,id相同的认为是一组,从上往下执行,所有组中,id值越大,优先级越高,越选执行;


03::02 select_type

  • SIMPLE : 简单SELECT,不使用UNION或子查询等;

  • PRIMARY: 主查询,即最外围的SELECT查询

  • SUBQUERY: 子查询中的第一个SELECT

  • DERIVED :在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询,把结果放在临时表中

  • UNION :若第二个SELECT出现在UNION之后,则被标记为UNION:若UNION包含在FROM子句的子查询中,外层SELECT将被标记为:DERIVED;

  • NION RESULT :从UNION表获取结果的SELECT


03::03 type (分析性能瓶颈的关键项之一)

显示连接使用了那种类型 , 有无索引 ,是使用explain 命令 分析性能瓶颈的关键项之一。
性能由差到好:
all > index > range >ref > eq_ref >const、system > null

03::03::01 【all】:遍历全表

遍历全表以找到匹配的行

explain select * from test_version


》》》》》》》》》》》》》》》》》》》》》》SQL执行计划分析:


03::03::02【index】:索引全扫描

索引全扫描,Index与All区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。(也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘读取的)。

explain select id from test o


》》》》》》》》》》》》》》》》》》》》》》SQL执行计划分析:


03::03::03【range】:索引范围扫描 ,常见于 <,>,between,in等待查询

explain select * from test_version p where p.id >1;


》》》》》》》》》》》》》》》》》》》》》》SQL执行计划分析:


03::03::04【ref】:非唯一性索引扫描或唯一索引的前缀扫描

explain select * from test p where p.age = ‘21’ ;


》》》》》》》》》》》》》》》》》》》》》》SQL执行计划分析:


03::03::05 【eq_ref】:唯一性索引扫描

唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。
即多表联查中使用primary key 和 unique index 作为关联条件。

SELECT p.id from test_version o left join test p on o.id = p.id where p.age = ‘21’ ;


》》》》》》》》》》》》》》》》》》》》》》SQL执行计划分析:


03::03::06 【const】:通过索引一次就找到

explain select * from test_version where id = 1


》》》》》》》》》》》》》》》》》》》》》》SQL执行计划分析:


03::03::07 【system】: 表只有一行记录(等于系统表)

表只有一行记录(等于系统表)


03::03::08 【null】不用访问表和索引,直接能查到结果

explain select 1 from dual;


》》》》》》》》》》》》》》》》》》》》》》SQL执行计划分析:
<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

03::04 filtered 返回结果的行占需要读到的行(rows列的值)的百分比

filtered表示返回结果的行数占需读取行数的百分比 Filtered列的值越大越好 Filtered列的值依赖于统计信息。


03::05 extra 额外信息展示

不适合在其他字段中显示,但是十分重要的额外信息:

序号extra内容含义
1using index使用了覆盖索引,避免访问了表的数据行,效率不错
2using where使用了where过滤
3using temporary意味着对查询结果进行排序的时候使用了一张临时表
4using filesort对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。MySQL中无法利用索引完成的排序操作称为“文件排序”。
5impossible wherewhere子句的值总是false,不能用来获取任何数据
6using join buffer表明使用了连接缓存,比如说在查询的时候,多表join的次数非常多,那么将配置文件中的缓冲区的join buffer调大一些。

04 mysql 优化 explain 和show warnings 用法

explain 的 extended扩展能够在原本explain的基础上额外提供一些查询优化的信息。
例子:

优化 select * from test where 1=1 and age = ‘21’;

优化信息通过 show warnings ;命令得到:

explain extended select * from test where 1=1 and age = ‘21’;
show warnings ;

>>>>>>>>>>>>>>>>>>>>>>>>>>>对比:>>>>>>>>>>>>>>>>>>>>>>>>>

优化前:

select * from test where 1=1 and age = ‘21’;

优化后:

/* select#1 */ select testdb.test.id AS id,testdb.test.age AS age,testdb.test.name AS name from testdb.test where (testdb.test.age = ‘21’)

我们可以发现优化器自动去除了1=1

分享到此结束、感谢观看,点赞、评论、收藏一健三连哦!!!

2022深度学习开发者峰会 5月20日13:00让我们相聚云端,共襄盛会!

以上是关于SQL调优带您涨薪资-explian分析SQL执行计划并优化的主要内容,如果未能解决你的问题,请参考以下文章

SQL调优带您涨薪资之show profile分析sql性能

SQL调优带您涨薪资之慢查询定位大法

SQL 执行计划

explian执行计划

sql server 性能调优之 当前用户请求分析

数据库学习——SQL调优