这是我参与「第五届青训营 」伴学笔记创作活动的第 10 天
今天学习了mysql在慢查询的排查流程以及具体的常见慢查询的种类
-
慢查询优化思路
- 慢查询日志记录慢SQL
- explain分析SQL的执行计划
- profile 分析执行耗时
- Optimizer Trace分析详情
- 确定问题并采用相应的措施
-
type表示连接类型,查看索引执行情况的一个重要指标。以下性能从好到坏依次:
system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL- system:这种类型要求数据库表中只有一条数据,是
const类型的一个特例,一般情况下是不会出现的。 - const:通过一次索引就能找到数据,一般用于主键或唯一索引作为条件,这类扫描效率极高,,速度非常快。
- eq_ref:常用于主键或唯一索引扫描,一般指使用主键的关联查询
- ref : 常用于非主键和唯一索引扫描。
- ref_or_null:这种连接类型类似于
ref,区别在于MySQL会额外搜索包含NULL值的行 - index_merge:使用了索引合并优化方法,查询使用了两个以上的索引。
- unique_subquery:类似于
eq_ref,条件用了in子查询 - index_subquery:区别于
unique_subquery,用于非唯一索引,可以返回重复值。 - range:常用于范围查询,比如:between ... and 或 In 等操作
- index:全索引扫描
- ALL:全表扫描
- system:这种类型要求数据库表中只有一条数据,是
-
常见慢查询的12个原因
-
隐式转换
- 使用了字符串类型的索引,但是传递的是数值,则系统将数值类型的数看做是隐式转换不走索引
-
不符合最左匹配原则
-
深分页问题
- 由于limit的使用不当导致检索了大量信息
- 可以使用标签记录法和延迟关联法解决
-
使用查询的in中的元素过多
-
order by 走文件排序导致速度过慢(其实就是查询的暂存量过大导致需要借助磁盘,解决方法如下)
- 因为数据是无序的,所以就需要排序。如果数据本身是有序的,那就不会再用到文件排序啦。而索引数据本身是有序的,我们通过建立索引来优化
order by语句。 - 我们还可以通过调整
max_length_for_sort_data、sort_buffer_size等参数优化;
- 因为数据是无序的,所以就需要排序。如果数据本身是有序的,那就不会再用到文件排序啦。而索引数据本身是有序的,我们通过建立索引来优化
-
索引字段上使用(!= 或者 < >),索引可能失效
-
索引字段上使用is null, is not null,索引可能失效
-
当左右的数据使用的编码集不同时,该使用索引的反而不使用索引
-
使用groupby不当导致占用了大量内存
-
group by使用不当,很容易就会产生慢SQL问题。因为它既用到临时表,又默认用到排序。有时候还可能用到磁盘临时表。- 如果执行过程中,会发现内存临时表大小到达了上限(控制这个上限的参数就是
tmp_table_size),会把内存临时表转成磁盘临时表。 - 如果数据量很大,很可能这个查询需要的磁盘临时表,就会占用大量的磁盘空间
- 如果执行过程中,会发现内存临时表大小到达了上限(控制这个上限的参数就是
-
-
delete + in子查询不走索引
-
-
慢查询更慢的12个原因:盘点MySQL慢查询的12个原因 (qq.com)