写点什么

对 Indexlookup 的理解误区

  • 2022 年 7 月 11 日
  • 本文字数:1212 字

    阅读完需:约 4 分钟

作者: h5n1 原文来源:https://tidb.net/blog/e09b5872


   在了解IndexLookUp执行过程前,先介绍下mysql索引扫描的执行作为对比(此处借用网络图),一条SQL执行时在存储引擎侧首先通读取索引中符合条件记录的主键(可能涉及ICP、组合索引部分列等),然后根据主键去表中读取记录,之后将记录返回给server层,再由server层根据其他条件进行过滤后返回客户端。上述过程中索引扫描和回表操作都是在存储引擎侧完成。
![image.png](https://tidb-blog.oss-cn-beijing.aliyuncs.com/media/image-1649379336703.png)![](file:///C:\Users\unicom\AppData\Local\Temp\msohtmlclip1\01\clip_image002.png)
IndexLookUp算子是tidb通过扫描索引然后通过rowid回表的扫描过程,包含2个子算子IndexScan和TableRowidscan,其中IndexLookUp算子的执行计划task列为root表示该算子在tidb server侧执行,2个子算子的task列为cop\[tikv]表示coprocessor task下推到tikv执行,在执行计划中算子的执行顺序是先执行子算子然后返回数据给父算子,对于并列深度的子算子上面的先执行(build端),然后用返回结果执行另一个算子(probe端),但执行过程中并不严格要求所有算子都是执行完后才返回结果或者子算子全部完成后才向父算子返回结果。
复制代码




   官方文档中对IndexLookUp介绍如下:
先汇总 Build 端 TiKV 扫描上来的 RowID,再去 Probe 端上根据这些 RowID 精确地读取 TiKV 上的数据。Build 端是 IndexFullScan 或 IndexRangeScan 类型的算子,Probe 端是 TableRowIDScan 类型的算子。
一直以来由于对子算子(IndexScan和TableRowidscan)在tikv中执行想当然的认为索引扫描和mysql一样都是在存储引擎一侧完成,导致对IndexLookUp执行过程有错误的认识:在tikv端通过索引扫描获得rowid后在tikv内使用rowid回表查询,最后将结果返回给tidb server再次过滤或返回客户端。
实际上IndexLookUp执行过程如下:
(1) tidb server根据SQL条件构造index scan的cop task,在tikv侧扫描索引获得符合条件的rowid.
(2) 扫描出来的rowid返回给tidb server进行汇总, tidb server根据rowid构造Key和cop task执行回表操作
(3) tikv使用TableRowIDScan回表扫描数据,然后将数据返回tidb,执行计划中的时间包括网络时间。
相比于mysql直接在引擎内直接回表查询,tidb IndexLookUp执行过程中要多2次网络交互,不可避免的会造成延迟,因此网络性能、tidb server的处理能力对IndexLookUp性能有一定影响。
Tidb有相关参数控制indexlookup的性能:
tidb\_index\_lookup\_size:使用rowid扫描表时一个批次处理的数量
tidb\_index\_lookup\_concurrency:使用rowid扫描表时的并发数。
复制代码


测试 1: tidb_index_lookup_concurrency 影响


   Concurrency由5降为1后,执行时间由6.15秒增长为26.57秒
复制代码




测试 2:tidb_index_lookup_size 影响


   相比较提高并发数tidb\_index\_lookup\_concurrency提升效果不是很明显
复制代码




发布于: 刚刚阅读数: 2
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
对Indexlookup的理解误区_管理与运维_TiDB 社区干货传送门_InfoQ写作社区