技术开发 频道

MySQL物理查询优化技术index dive辨析

  【IT168 技术】一 引子

  在MySQL的官方手册上有这么一句话:

  the optimizer can estimate the row count for each range using dives into the index or index statistics.

  这是在说: 优化器为每一个范围段(如“a IN (10, 20, 30)”包括2个范围段,一是10到20,二是20到30)估计这个范围段中包括的元组数, 而估计方法有2种,一是dive到index中即利用索引完成元组数的估算,简称index dive; 二是使用索引的统计数值,进行估算。

  相比这2种方式,在效果上:

  1 index dive: 速度慢,但能得到精确的值;

  2 index statistics: 速度快,但得到的值未必精确。

  二 深入

  为什么要区分这两种方式呢?

  简单地说:

  1 查询优化器使用代价估算模型计算每个计划的代价,选择其中代价最小的;

  2 单表扫描时,需要计算代价;所以单表的索引扫描也需要计算代价;

  3 单表的计算公式通常是:代价=元组数*IO平均值;

  4 所以不管是哪种扫描方式,都需要计算元组数;

  5 当遇到“a IN (10, 20, 30)”这样的表达式的时候,发现a列存在索引,则需要看这个索引可以扫描到的元组数由多少而计算其索引扫描代价,所以就用到了本文提到的“index dive”、“index statistics”这2种方式。

  三 优化

  MySQL据此,提供了一个参数“eq_range_index_dive_limit”,指示MySQL在这种情况下使用哪种方式。用法如下:

  This variable indicates the number of equality ranges in an equality comparison condition when the optimizer should switch from using index dives to index statistics in estimating the number of qualifying rows. It applies to evaluation of expressions that have either of these equivalent forms, where the optimizer uses a nonunique index to look up col_name values:

  col_name IN(val1, ..., valN)

  col_name = val1 OR ... OR col_name = valN

  参考资料:

  1 MySQL官方博客:http://mysqlserverteam.com/you-asked-for-it-new-default-for-eq_range_index_dive_limit/

  2 一个实例:http://imysql.com/2014/08/05/a-fake-bug-with-eq-range-index-dive-limit.shtml

0
相关文章