Mysql执行计划的extra列及filesort祥析

Extra列显示Mysql解析查询的附加信息。有如下取值:

1. Impossible Where

WHERE条件恒不满足,结果集为空

2. Impossible Having

HAVING条件恒不满足,结果集为空

3. Using index

表示查询所需的信息直接通过索引获取,未读取实际的数据行。

有两种情况,一种是Mysql的聚簇索引(Cluster Index),因为聚簇索引将索引信息和数据信息组织在了一起。(对于InnoDB来说,通常主键即是聚簇索引,若未定义主键,则InnoDB会选择一个唯一的非空索引替代,如果这种索引不存在,则会隐式定义一个主键)

另一种是覆盖查询,即查询所需的列已在索引中包含。

4. Using index condition

表示通过索引下推(ICP, Index Condition Pushdown)优化进行数据的过滤。即:首先通过索引检查是否满足部分查询条件,若不满足,则不会再读取整行数据进行校验,若满足,再读取整行数据进行剩余条件校验。通过这种方式,减少了完整数据的获取次数。

5. Using index for group-by

Mysql通过索引完成Group By或者Distinct操作,而不需要读取所有的数据,去重生成临时表的方式完成Group By。通过这种方式避免对磁盘的直接读取。

6. Using join buffer (Block Nested Loop), Using join buffer (Batched KeyAccess)

表示前表的部分结果被读取到join buffer中,在与当前表做join时,直接从buffer中读取。

7. Using MRR

使用MRR(Multi-Range Read)优化来读取表数据。

在表数据未缓存到存储引擎缓存中的情况下,通过二级索引(secondary index)进行范围查找时,会导致很多随机的读磁盘,导致明显的性能问题,MRR优化正是为了解决这一问题。总的来说,MRR通过对二级索引扫描、排序(根据row_id)后,通过主键来顺序读取数据,避免大量的随机磁盘那读取。

MRR优化是5.6版本后Mysql引入的新特性。对于覆盖查询或者需要读取全表数据的情况,Mysql不会使用MRR优化,因为并不会产生优化效果。

MRR优化通过mrr及mrr_cost_based(控制mysql基于cost来判断是否使用MRR优化)变量来控制,默认地,两个开关都是打开的状态。

8. Using filesort

Mysql需要在执行一次额外的排序使查询结果有序。

8.1. ORDER BY 与索引

当满足某些情况时,Mysql可以对ORDER BY利用索引获得有序的结果,而不需要额外的排序:

l 最简单的,ORDER BY 指定的列上创建了独立的索引

l 联合索引,ORDER BY 指定的多列满足索引顺序;或者索引中未指定排序的列已在WHERE条件中限定了常量条件;或者最左前缀列在WHERE条件中限定了范围,并且依据该列排序。等等…

以下情况ORDER BY不会走索引:

l 排序各列属于不同的索引

l 不满足最左前缀

l 混用ASC, DESC

l WHERE条件限定的筛选范围列于排序列所属索引不同

l 多表联合查询的情况下,ORDER BY 条件列不全部属于第一个非常量表(type列为const)

l 排序列上仅创建部分索引

在未显式指定ORDER BY的情况下,Mysql默认会对GROUP BY做排序。如果想避免隐式排序带来的附加消耗,可以通过指定ORDER BY NULL避免排序。但是,官方不推荐依赖于GROUP BY的隐式排序来获得有序的结果,因为Mysql在后续可能去除隐式排序的特性。

8.2. filesort算法

Mysql有两种默认的filesort算法,区别在于排序期间读取整行数据的次数为一次或者两次,显然次数为一次的更优。如果结果列中没有TEXT或者BLOB类型的列,则Mysql会优先选择更优的算法,其步骤如下:

1. 读取满足WHERE条件的所有数据行

2. 对每一行,记录由排序键、行位置及结果列组成的tuple至buffer,buffer的大小由sort_buffer_size参数指定

3. 以排序键排序

4. 以排序后的tuple为基础,返回有序的结果列

另一种排序算法,其步骤如下:

1. 根据索引或者全表扫描的方式,逐行读取满足WHERE条件的所有列

2. 对每一行,记录由排序键、行位置组成的tuple至buffer,buffer的大小由sort_buffer_size参数指定

3. 当buffer满后,使用快排进行排序并将结果保存到临时文件中(temporary file)。并记录该文件的指针(若首次即读完所有所需的记录,则不需创建临时文件)

4. 重复执行1-3,直到所有行读取完毕

5. 对第三步中的临时文件做归并,并将结果保存到另一个临时文件中。重复执行,直至所有的结果都保存到第二个文件中。在最后一次归并中,仅保存行指针至结果文件

6. 利用结果文件保存的行指针有序读取结果并返回。

使用优化算法的情况下,可能会由于待排序结果超过sort_buffer_size的大小而导致额外的I/O。为了避免这种情况,Mysql通过参数max_length_for_sort_data来限定,如果所有结果列的长度超过该长度,则不会使用优化的算法。

最后,如果无法通过索引来优化ORDER BY,导致filesort,可以通过以下策略来进一步优化:

l 提高sort_buffer_size的大小设置

l 提高read_rnd_buffer_size的大小设置

l 定义列时,满足需求的情况下,尽可能使用更短的类型长度

l 将tmpdir指定到空闲空间更大的硬盘

9. Using temporary

通常在查询包含GROUP BY或者ORDER BY时出现。表示Mysql为了执行查询,需要创建临时表来存放临时结果。

10. Using where

语句通过WHERE限定了与连接表连接的范围或者发送客户端的结果范围。如果不是查全部列,当type列为ALL或者index时,如果Extra列无Using where,则查询可能存在问题。

11. Using where with pushed condition

仅针对NDB引擎的表;表示NDB Cluster使用了条件下推优化(Condition PushDown optimization)来提升非索引列的等值条件查询(LIKE/BETWEEN…AND…/IN 也支持)。在这种场景下,条件被下推到集群的数据节点同时执行,避免了发送不满足条件的数据。此优化通常可以有5-10倍的性能提升。

转载于:https://www.cnblogs.com/luojiahu/p/10889784.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值