MySQL MRR 索引检索优化之 key/rowid 排序

DS-MRR

  • mrr function calls

  • Key-Ordered Retrieval
    关键思想:如果 MRR 扫描类似于:

    tbl.key=value1 OR tbl.key=value2 OR ... OR tbl.key=valueN  
    

    那么将要查询的条件进行收集并且排序,例如:

     sort(value1, value2, .. valueN)  
    

    然后按照索引顺序进行索引检索,就会减少的索引页 page 的 fetch 操作。

  • Rowid-Ordered Retrieval
    如果做一个索引的常规扫描或者一系列索引的扫描,那么检索到记录将会是一个随机 IO。基于磁盘的引擎,这将远远慢于按磁盘顺序检索读取记录。假设记录在磁盘上的顺序是以 rowid 的顺序进行组织的(handler::cmp_ref()提供比较)。

    如果要按照不同的顺序进行检索记录,必须区分索引扫描和记录读取,为了达到这个目录,MRR 扫描有以下步骤原则:
    1 扫描索引(只是索引,HA_EXTRA_KEYREAD),然后用记录的{rowid,range_id}来填充一个 buffer。
    2 按照 rowid 对 buffer 进行排序。
    3 对于 buffer 中的每一对{rowid, range_id},根据 rowid 获取记录并且返回{record, range_id}记录对。
    4 重复以上步骤,直到扫描完了一个 range。

  • 缓冲区空间管理注意事项
    关于缓冲区/内存管理,MRR接口指定:

    • SQL 层提供 multi_range_read_init 和一块指定大小的缓存区。
    • MRR 实现可能会使用(即直到 MRR 扫描结束)所有缓存区,或返回未使用的缓存区回给 SQL 层。

    DS-MRR 需要缓存区以排序 rowid 或者索引键。至于什么情况下需要排序 rowid 或索引键,条件是相当琐碎的。

    当我们需要对键和rowid进行排序时,使用缓存将会变得比较复杂。需要:

    • 首先,收集 keys 然后对其进行排序;
    • 然后使用 keys(较小的值排在最前面)获取行rowid。在获得完匹配的 rowid 之后, keys 就不再需要了。
    • 确保使得 rowid 在缓冲区的前面,以便我们
      可以将缓冲区的结尾部分返回到SQL层,以使很少的 rowid 值占用缓冲区。

    通过使用以下方案可以实现所有这些目标:

    
     |                    |   从SQL层获取一块空缓存;   
    
     |                  *-|    
     |               *----|   首先,用 keys 值填充 buffer,Key_buffer 部分
     |            *-------|   从 buffer 尾部向前涨
     |         *----------|   (这个示例图中,buffer 大的足够放下所有 key,
     |      *-------------|    放完了所有key值后,还有剩余空间)
    
     |      *=============|   我们想要做 key-ordered index 扫描, 所以进行排序
    
     |-x      *===========|   然后使用 keys 来获取 rowids. Rowids 以
     |----x      *========|   buffer space 的头部向尾部增长的方式存储。
     |--------x     *=====|   buffer 中的部分 keys 内容逐渐可以进行释放,
     |------------x   *===|   以释放空间给 rowids 存储. 在这个示例图中,
     |--------------x   *=|   我们所有的 keys 都释放完后,
     |----------------x   |   buffer 空间还有剩余。
    
     |================x   |   然后对 rowids 进行排序.
                     
     |                |~~~|   buffer 未使用的部分在尾部, 所以
                              我们可以将其释放回给 SQL 层.
    
     |================*       排序后的 rowids 被用来按磁盘顺序来读取 table records 
                              
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抡着鼠标扛大旗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值