zoukankan      html  css  js  c++  java
  • MySQL 5.6 优化点(MRR、BKA 与 ICP)

    最近在学习 MySQL 相关的东西,大致整理一下

    MRR —— Multi-Range Read Optimization

    MRR 是优化器将随机 IO 转化为顺序 IO,以降低 IO 开销的手段。

    二级索引中存储的是索引列和主键值,当查询列不都存在与索引列中时(即不是覆盖索引的情况),需要回表操作。然而回表获取完整用户记录可能回产生随机 IO(当数据量较多且比较分散时,随机 IO 性能较低,后会单写一篇「表空间」的笔记),为减少这种随机 IO,MySQL 首先只在二级索引中查询,统计关联行的主键,然后根据主键值排序, 最后从聚簇索引中按照主键排序获取完整记录。

    使用 MRR 时的查询过程:

    1. 优化器将从二级索引中查询到的记录放到缓冲区中;
    2. 如果缓冲区已满,或者扫描到二级索引文件末尾,使用快排对缓冲区的数据按照主键排序;
    3. 用户线程根据缓冲区的内容,从聚簇索引中获取数据;
    4. 当缓冲区内容读取完毕时,重复上述过程,直到扫描结束

    如何查看一条 SQL 是不是 MRR 呢?我们 EXPLAIN 执行一条 SQL 时,使用 MRR 的查询会在 Extra 列出现 Using MRR 关键字。

    optimizer_switch 变量控制是否开启 MRR,默认是开启的,关闭的话 set optimizer_switch = 'mrr=off'

    ICP —— Index Condition Pushdown Optimization(索引下推)

    2020-01-18 更新索引下推的分析,添加 Index Key、Index Filter 与 Table Filter。

    这个就比较常见了,MySQL 分层架构中最上面是负责管理连接的,第二层是 Server 层用来语法解析、查询优化的,最后一层是存储引擎层来和文件系统打交道的。

    强烈推荐阅读何登成大佬 where 条件在数据库中提取与应用浅析 这篇文章,where 条件可以分为三大类,分别是 Index Key(First Key、Last Key)、Index Filter 以及 Table Filter。

    Index Key

    用于确认索引查询范围,既然是范围肯定有开头有结束,分别对应 Index First Key 与 Index Last Key。

    Index First Key 的提取从索引第一列开始,依次对全部索引列进行如下判断,判断 where 条件中是否有针对该列的 >=、= 条件,如果有就将该条件加到 Index First Key 中,并查找下一个索引列;where 条件如果有针对该列的 > 条件,同样将该条件添加到 Index First Key 中并终止 Index First Key 的提取。

    Index Last Key 的提取与上面 First Key 类似,只是变成了 <。仍旧从索引第一列开始,判断 where 条件是否有针对该列的 <=、= 条件,如果有就将该条件添加到 Index Last Key 中,并查找下一个索引列;where 条件中如果有针对该列的 < 条件,同样将该条件加到 Index Last Key 中并终止 Index Last Key 的提取。

    Index Filter

    通过对 Index Key 的提取,我们从二级索引对应的 B+ 树中确认了二级索引的扫描范围,但并不代表该范围内的每一项都满足查询条件(这里说的是二级索引包含的列)。何大佬写的 Index Filter 查询过程看了好多遍,实在没看明白,贴图过来以后看。

    在这里插入图片描述
    Index First Key 用来确认索引的起始范围,只进行一次判断,从 B+ 树根节点开始往下遍历,直到找到正确的叶节点位置(并定位其中的索引项)。Index Last Key 则是用来定位索引的终止范围,对确定了起始范围之后读取到的每个索引记录,均需要判断是否超过了 Index Last Key 的范围(超过了就结束索引列的查询),同时还要与 Index Filter 对比(不满足 Index Filter 条件就丢弃,继续读取下一条记录)。

    Table Filter

    所有在索引列中不存在的查询条件,均属于 Table Filter。既然这个查询条件在索引列中不存在,肯定需要回表查询,何大佬写的太经典了,直接抄过来了。

    Table Filte 是最后一道 where 条件的防线,用于过滤通过前面索引的层层考验的记录,此时的记录已经满足了 Index First Key 与 Index Last Key 构成的范围,并且满足 Index Filter 的条件,回表读取了完整的记录,判断完整记录是否满足 Table Filter 中的查询条件,同样的,若不满足,跳过当前记录,继续读取索引的下一条记录,若满足,则返回记录,此记录满足了 where 的所有条件,可以返回给前端用户。

    MySQL 5.6 之前不区分 Index Filter 还是 Table Filter,存储引擎层找到满足 Index Key 的所有二级索引记录后,都会回表取完整记录,然后由 Server 层来对 WHERE 条件做过滤。有 ICP 后,Index Filter 这部分就交给存储引擎层去做了。

    这么做的优点呢?一是减少了回表的开销,二是减少了存储引擎层返回 Server 层的时间。

    ICP 支持 InnoDB 和 MyISAM 引擎,对于 InnoDB ICP 只支持二级索引,不支持聚簇索引,因为聚簇索引的全部数据都从 InnoDB Buffer 中读取,不涉及磁盘 IO。在二级索引是复合索引且前面的条件过滤性较低的情况下,打开 ICP 可以有效的降低 Server 层和 Engine 层之间交互的次数,从而有效的降低在运行时间。

    The goal of ICP is to reduce the number of full-row reads and thereby reduce I/O operations. For InnoDB clustered indexes, the complete record is already read into the InnoDB buffer. Using ICP in this case does not reduce I/O.

    ICP 也有一些限制条件:

    1. 不适用于子查询、不支持主键索引
    2. ICP的优化策略可用于range、ref、eq_ref、ref_or_null 类型的访问数据方法

    EXPLAIN 时,使用 ICP 的查询会在 Extra 列出现 Using index condition 关键字。

    Reference

  • 相关阅读:
    Neko's loop HDU-6444(网络赛1007)
    Parameters
    SETLOCAL
    RD / RMDIR Command
    devenv 命令用法
    Cannot determine the location of the VS Common Tools folder.
    'DEVENV' is not recognized as an internal or external command,
    How to change Visual Studio default environment setting
    error signing assembly unknown error
    What is the Xcopy Command?:
  • 原文地址:https://www.cnblogs.com/Zhoust/p/14994593.html
Copyright © 2011-2022 走看看