共计 3401 个字符,预计需要花费 9 分钟才能阅读完成。
本篇内容主要讲解“怎么精通 SQL 优化”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“怎么精通 SQL 优化”吧!
Explain 有哪些信息
先确认一下试验的 MySQL 版本,这里使用的是 5.7.31 版本。
只需要在 SQL 语句前加上 explain 关键字就可以查看执行计划,执行计划包括以下信息:id、select_type、table、partitions、type、possible_keys、key、key_len、ref、rows、filtered、Extra,总共 12 个字段信息。
然后创建三个表:
CREATE TABLE `tb_student` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(36) NOT NULL, PRIMARY KEY (`id`), KEY `index_name` (`name`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT= 学生表 CREATE TABLE `tb_class` ( `id` INT(10) primary key not null auto_increment, `name` VARCHAR(36) NOT NULL, `stu_id` INT(10) NOT NULL, `tea_id` INT(10) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT= 班级表 CREATE TABLE `tb_teacher` ( `id` INT(10) primary key not null auto_increment, `name` VARCHAR(36) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT= 教师表
Explain 执行计划详解
explain 的使用很简单,只需要在 SQL 语句前加上关键字 explain 即可,关键是怎么看 explain 执行后返回的字段信息,这才是重点。
一、id
SELECT 识别符。这是 SELECT 的查询序列号。SQL 执行的顺序的标识,SQL 从大到小的执行。id 列有以下几个注意点:
id 相同时,执行顺序由上至下。
id 不同时,如果是子查询,id 的序号会递增,id 值越大优先级越高,越先被执行。
EXPLAIN SELECT * FROM `tb_student` WHERE id IN (SELECT stu_id FROM tb_class WHERE tea_id IN(SELECT id FROM tb_teacher WHERE `name` = 马老师
根据原则,当 id 不同时,SQL 从大到小执行,id 相同则从上到下执行。
二、select_type
表示 select 查询的类型,用于区分各种复杂的查询,例如普通查询,联合查询,子查询等等。
SIMPLE
表示最简单的查询操作,也就是查询 SQL 语句中没有子查询、union 等操作。
PRIMARY
当查询语句中包含复杂查询的子部分,表示复杂查询中最外层的 select。
SUBQUERY
当 select 或 where 中包含有子查询,该子查询被标记为 SUBQUERY。
DERIVED
在 SQL 语句中包含在 from 子句中的子查询。
UNION
表示在 union 中的第二个和随后的 select 语句。
UNION RESULT
代表从 union 的临时表中读取数据。
EXPLAIN SELECT u.`name` FROM ((SELECT s.id,s.`name` FROM `tb_student` s) UNION (SELECT t.id,t.`name` FROM tb_teacher t)) AS u;
代表是 id 为 2 和 3 的 select 查询的结果进行 union 操作。
MATERIALIZED
MATERIALIZED 表示物化子查询,子查询来自视图。
三、table
表示输出结果集的表的表名,并不一定是真实存在的表,也有可能是别名,临时表等等。
四、partitions
表示 SQL 语句查询时匹配到的分区信息,对于非分区表值为 NULL,当查询的是分区表则会显示分区表命中的分区情况。
五、type
需要重点关注的一个字段信息,表示查询使用了哪种类型,在 SQL 优化中是一个非常重要的指标,依次从优到差分别是:system const eq_ref ref range index ALL。
system 和 const
单表中最多有一条匹配行,查询效率最高,所以这个匹配行的其他列的值可以被优化器在当前查询中当作常量来处理。通常出现在根据主键或者唯一索引进行的查询,system 是 const 的特例,表里只有一条元组匹配时 (系统表) 为 system。
eq_ref
primary key 或 unique key 索引的所有部分被连接使用 ,最多只会返回一条符合条件的记录,所以这种类型常出现在多表的 join 查询。
ref
相比 eq_ref,不使用唯一索引,而是使用普通索引或者唯一性索引的部分前缀,可能会找到多个符合条件的行。
range
使用索引选择行,仅检索给定范围内的行。一般来说是针对一个有索引的字段,给定范围检索数据,通常出现在 where 语句中使用 bettween…and、、、=、in 等条件查询。
index
扫描全表索引,通常比 ALL 要快一些。
ALL
全表扫描,MySQL 遍历全表来找到匹配行,性能最差。
六、possible_keys
表示在查询中可能使用到的索引来查找,而列出的索引并不一定是最终查询数据所用到的索引。
七、key
跟 possible_keys 有所区别,key 表示查询中实际使用到的索引,若没有使用到索引则显示为 NULL。
八、key_len
表示查询用到的索引 key 的长度(字节数)。如果单列索引,那么就会把整个索引长度计算进去,如果是联合索引,不是所有的列都用到,那么就只计算实际用到的列,因此可以根据 key_len 来判断联合索引是否生效。
九、ref
显示了哪些列或常量被用于查找索引列上的值。常见的值有:const,func,null,字段名。
十、rows
mysql 估算要找到我们所需的记录,需要读取的行数。可以通过这个数据很直观的显示 SQL 性能的好坏,一般情况下 rows 值越小越好。
十一、filtered
指返回结果的行占需要读到的行 (rows 列的值) 的百分比,一般来说越大越好。
十二、Extra
表示额外的信息。此字段能够给出让我们深入理解执行计划进一步的细节信息。
Using index
说明在 select 查询中使用了覆盖索引。覆盖索引的好处是一条 SQL 通过索引就可以返回我们需要的数据。
Using where
查询时没使用到索引,然后通过 where 条件过滤获取到所需的数据。
Using temporary
表示在查询时,MySQL 需要创建一个临时表来保存结果。临时表一般会比较影响性能,应该尽量避免。
有时候使用 DISTINCT 去重时也会产生 Using temporary。
Using filesort
我们知道索引除了查询中能起作用外,排序也是能起到作用的,所以当 SQL 中包含 ORDER BY 操作,而且无法利用索引完成排序操作的时候,MySQL 不得不选择相应的排序算法来实现,这时就会出现 Using filesort,应该尽量避免使用 Using filesort。
总结
一般优化 SQL 语句第一步是要知道这条 SQL 语句有哪些需要优化的,explain 执行计划就相当于一面镜子,能把详细的执行情况给开发者列出来。所以说善用 explain 执行计划,能解决 80% 的 SQL 优化问题。
explain 的信息中,一般我们要关心的是 type,看是什么级别,如果是在互联网公司一般需要在 range 以上的级别,接着关心的是 Extra,有没有出现 filesort 或者 using template,一旦出现就要想办法避免,接着再看 key 使用的是什么索引,还有看 filtered 筛选比是多少。
到此,相信大家对“怎么精通 SQL 优化”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!