select name,age from A where zip=0 (修改zip为int类型)
TiDB字段尽量使用常见mysql类型
注意:analyze tableName对TiDB集群的影响较大 , 执行前千万与DBA做好沟通评估 , 临时情况可通过显示指定索引(USE INDEX)绕开流量高峰期
五、 TiDB执行计划分析简介1. 在开始实际案例分析前 , 我们先看下执行计划中每列的含义:引自:
https://docs.pingcap.com/zh/tidb/stable/sql-statement-explain和https://docs.pingcap.com/zh/tidb/stable/sql-statement-explain-analyze
属性名
含义
id
算子的 ID , 是算子在整个执行计划中唯一的标识 。在 TiDB 2.1 中 , ID 会格式化地显示算子的树状结构 。数据从孩子结点流向父亲结点 , 每个算子的父亲结点有且仅有一个 。
estRows
算子预计将会输出的数据条数 , 基于统计信息以及算子的执行逻辑估算而来 。
actRows
算子实际输出的数据条数
task
算子属于的 task 种类 。目前的执行计划分成为两种 task , 一种叫 root task , 在 tidb-server 上执行 , 一种叫 cop task , 在 TiKV 或者 TiFlash 上并行执行 。当前的执行计划在 task 级别的拓扑关系是一个 root task 后面可以跟许多 cop task , root task 使用 cop task 的输出结果作为输入 。cop task 中执行的也即是 TiDB 下推到 TiKV 或者 TiFlash 上的任务 , 每个 cop task 分散在 TiKV 或者 TiFlash 集群中 , 由多个进程共同执行 。
access object
算子所访问的数据项信息 。包括表 table , 表分区 partition 以及使用的索引 index(如果有) 。只有直接访问数据的算子才拥有这些信息 。
execution info
算子的实际执行信息 。time 表示从进入算子到离开算子的全部 wall time , 包括所有子算子操作的全部执行时间 。如果该算子被父算子多次调用 (loops) , 这个时间就是累积的时间 。loops 是当前算子被父算子调用的次数 。
operator info
算子的其它信息 。各个算子的 operator info 各有不同 , 可参考下面的示例解读 。
memory
算子占用内存空间的大小
disk
算子占用磁盘空间的大小
2. 执行计划优化的几个关键点:1) 重点观察算子类型 , 尽量控制优化器选择性能较优的算子 , 读取磁盘记录的几个算子性能:TableFullScan>TableRangeScan>TableRowIDScan , IndexFullScan>IndexRangeScan
2) 尽量减小root层执行动作 , 下放至tikv或tiflash执行 , 执行计划中task属性包括root task和cop task , 其中root标识动作由tidb聚合层执行(此操作除了需要等待各分片结果外 , 一般部署结构中tidb资源也较tikv或tiflash少) , cop标识动作下放至tikv或tiflash各分片单独执行
3) 保证表分析数据完整性 , 避免大批量数据短时间内新增/删除 , estRows为执行引擎根据情况返回的预估记录条数 , 特别注意:若operator info出现stats:pseudo , 则标识表基本信息不完善(无法提供准确执行计划评估) , 后续可通过analyze表重新收集分析数据 , 或显示use index对sql显示优化
4) 根据实际业务(如:列模式数据统计) , 增加tiflash模块 , 通过空间换时间 , 提升结构化查询和实时分析能力
3. 实际场景分析下面我们通过2个实际SQL说说TiDB的执行计划:
l SQL1

文章插图
*1:IndexLookUp算子:根据索引获取结果记录
*2 & *3:Build算子总是优先于Probe算子执行 , *2 算子根据条件从索引中获取数据 , *3算子在结果中匹配结果
*4:TableRowIdScan:通过 *3 算子结果中的表主键id从TiKV获取行记录
*5:cop【tikv】标识将计算逻辑从tidb下放到tikv执行 , 同理还会有cop【tiflash】
*6:tikv通过范围索引扫描出对应记录
*7:根据id获取行记录后直接返回上层 , 无需排序
------------------------------------------------------------------------------------------------------------------------------
l SQL2
优化前 , 两表直接join:
explain analyze SELECT m.id AS id, m.order_id AS orderId, s.status AS status,m.sendpay_map as sendPayMap FROM tableA m LEFT JOIN tableB s on m.order_id = s.order_id WHERE m.id >= 100 AND m.id <= 100000000 and m.warehouse_id in (111,222) and s.status in (100, 200, 300, 400) and m.is_valid = 1 order by m.id desc limit 20,20;
推荐阅读
- 带你读 MySQL 源码:Select *
- 指针与内存对齐到底是什么鬼?
- 潮汕美食:探索舌尖上的美味与文化
- 生姜薏米水功效与作用
- 生姜紫苏水功效与作用
- 白酒泡樱桃功效与作用
- 于和伟|于和伟乱睡门后露面,与风波女主眼神躲闪刻意避嫌王丽坤再受累
- |解读电视剧《爱情而已》探寻当代人情感、职场与家庭之路
- 面膜泥的功效与作用,面膜泥的正确使用方法 面膜泥多久后洗掉?
- 附桂骨痛颗粒的功效与作用
