新的优化可以避免全量索引扫描,而是根据每个col1上的值+col2上的条件,启动多次range scan。每次range scan根据构建的key值直接在索引上定位,直接忽略了那些不满足条件的记录。

    示例 下例是从官方文档上摘取的例子:

    也可以从optimizer trace里看到如何选择的skip scan:

    • 第一次从Index left side开始scan
    • 使用key(1), find_flag =HA_READ_AFTER_KEY, 找到下一个Key值2
    • 使用Key(2),去找大于2的key值,上例中没有,因此结束扫描

    笔者在代码注入了日志,打印search_tuple(dtuple_print())

    从上述描述可以看到使用skip-scan的方式避免了全索引扫描,从而提升了性能,尤其是在索引前缀列区分度比较低的时候

    条件 skip scan可以通过Hint或者optimizer_switch来控制(skip_scan),默认是打开的。根据worklog的描述,对于如下query:

    ref: get_best_skip_scan()

    当skip scan拥有更低的cost时,会被选择,计算cost的函数是cost_skip_scan(),由于索引统计信息中已经基于不同的前缀列值估算了distinct value的个数(rec_per_key), 可以基于此去预估可能需要读的行数。 更具体的可以参考wl#11322中的描述,笔者对此不甚了解,故不做笔墨 ref: cost_skip_scan()

    官方文档:Skip Scan Range Access Method Bug#88103