TiDB与MySQL的SQL差异及执行计划简析( 三 )


TiDB与MySQL的SQL差异及执行计划简析

文章插图
*1:IndexJoin算子:根据表s索引 , 与表m关联起来
*2 & *3:Build算子总是优先于Probe算子执行 , *2 算子从表m匹配相关记录 , *3算子通过表s索引获取join管理数据
*4 & *5:基于*3算子join后的结果 , 筛选匹配s表条件的记录
*6 & *7:可以看到此处表记录查询使用了TableReader , 耗时6.41s(其中cop_task共424个 , 且使用了大量索引proc_keys) , Selection_98根据索引回表查询更是读取了3.03GB记录
总结:整体sql因为是先join在limit , tidb无法将limit操作下推 , 导致主表大量回表查询 , 影响性能
优化后 , 先子查询再join:
explain analyze select * from (SELECT m.id AS id, m.order_id AS orderId,m.sendpay_map as sendPayMap FROM tableA m WHERE m.id >= 100 AND m.id <= 100000000 and m.warehouse_id in (111 ,222) and m.is_valid = 1 order by m.id desc limit 20,20) t LEFT JOIN tableB s on t.orderId = s.order_id WHERE s.status in (100 ,200, 300, 400)
TiDB与MySQL的SQL差异及执行计划简析

文章插图
*1:IndexJoin算子:根据表s索引 , 与表m关联起来
*2:从m表结果中获取前20条记录
*3:通过表s索引获取join管理数据
*4:根据条件 , 从表m的索引中获取记录
*5:从*4算子结果中获取40条记录(tikv3副本 , 从2个分片各获取20条 , 共40条)
*6 & *7:基于*3算子join后的结果 , 筛选匹配s表条件的记录
*9:可以看到 , 此处是直接从IndexLookUp_57索引中查询数据 , cop_task=1 , 且rocksdb中命中了缓存cache_hit_count=11
总结:整体sql因为是先limit再join , tidb将limit下推至tikv , 大大较少了主表的回表查询数据量 , 提升性能
六、 小结本文旨在通过TiDB和MySQl在SQL层面的差异性讲解 , 帮助读者在DB迁移和评估前 , 清楚了解双方的差异 , 避免遗漏 。同时 , 针对TiDB的执行计划 , 通过简介和2个案例 , 帮助大家快速分析SQL执行情况 , 以便针对性优化 。

【TiDB与MySQL的SQL差异及执行计划简析】


推荐阅读