在理解IndexLookUp执行过程前,先介绍下mysql索引扫描的执行作为比照(此处借用网络图),一条SQL执行时在存储引擎侧首先通读取索引中符合条件记录的主键(可能波及ICP、组合索引局部列等),而后依据主键去表中读取记录,之后将记录返回给server层,再由server层依据其余条件进行过滤后返回客户端。上述过程中索引扫描和回表操作都是在存储引擎侧实现。
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晋升成果不是很显著
原文作者:@h5n1 发表于:2022/4/8
原文链接:https://tidb.net/blog/e09b5872