从执行计划里面看,能否确认这条sql语句耗时多少毫秒?,从最后执行完的结果看是440毫秒,但是这440毫秒跟这执行计划里面的时间好像对应不上。不是如何理解这执行计划的时间?
MySQL [xxxxxxxxx]> explain analyze select * FROM xxxxxxxxxxxx WHERE form_id = 1000968 AND form_user_id = 676601837 AND data_index_id > 0;
±-----------------------±--------±--------±----------±-------------------------------±-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------±---------------------------------------------------------------------±--------±-----+
| id | estRows | actRows | task | access object | execution info | operator info | memory | disk |
±-----------------------±--------±--------±----------±-------------------------------±-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------±---------------------------------------------------------------------±--------±-----+
| TableReader_7 | 0.02 | 170 | root | | time:87.7ms, loops:2, RU:18.324737, cop_task: {num: 1, max: 80.7ms, proc_keys: 170, tot_proc: 51ms, tot_wait: 77.9µs, rpc_num: 1, rpc_time: 80.7ms, copr_cache_hit_ratio: 0.00, build_task_duration: 7.13µs, max_distsql_concurrency: 1} | data:TableRangeScan_6 | 10.6 MB | N/A |
| └─TableRangeScan_6 | 0.02 | 170 | cop[tikv] | table:xxxxxxxxxx | tikv_task:{time:30ms, loops:3}, scan_detail: {total_process_keys: 170, total_process_keys_size: 47258, total_keys: 338, get_snapshot_time: 28µs, rocksdb: {key_skipped_count: 337, block: {cache_hit_count: 6, read_count: 3, read_byte: 95.4 KB, read_time: 55.1µs}}} | range:(1000968 676601837 0,1000968 676601837 +inf], keep order:false | N/A | N/A |
±-----------------------±--------±--------±----------±-------------------------------±-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------±---------------------------------------------------------------------±--------±-----+
2 rows in set (0.44 sec)
TableReader_7 耗时:87.7ms loops:2
TableRangeScan_6 耗时:30ms loops:3
计算结果是:87.72+303=265.4耗秒,跟上面语句输出的结果440ms,不一致?这个如何解释
0.44秒即440毫秒是客户端显示的执行总时间,应该是包含tidb server到你的客户端的网络时间和客户端展示的时间,执行计划中是每个步骤的时间。
执行计划里面的时间不是总时间?只是执行总时间里面的一部分吗?
是在数据库层面总时间,到你客户端还有时间
你用count不返回数据应该就是相近的
执行计划的第一行的时间,表示SQL语句在数据库里执行的总时间,是87.7ms。
SQL的执行过程
time 表示从进入算子到离开算子的全部 wall time,包括所有子算子操作的全部执行时间。如果该算子被父算子多次调用 (loops),这个时间就是累积的时间。loops 是当前算子被父算子调用的次数。
客户端显示的440ms = 执行计划中的87.7ms + 结果从db_server到客户端网络传输的时间。
执行计划并不能提前获取到db_server到客户端的时间。
tidb的执行计划一直不太懂,尤其是执行顺序
官方文档对explain介绍好像也不多,从执行计划来看从下往上
同缩进级别的上边先执行,不同缩进级别的,最右边的先执行
你的意思是同级别从上往下执行,不同级别的从下往上执行?
虽然可以这么理解,但是我不建议记这样的公式,其实tidb的执行计划和Oracle的比较像。你可以搜索Oracle的执行计划顺序网上文章一大堆,MySQL的执行计划顺序不直观,不好看。(MySQL有workbench,那里的图形化执行计划是很好看的)。当然最简单的是看tidb的官方文档,或者看免费视频,董老师有讲执行计划的视频。
先看官方文档吧
https://docs.pingcap.com/zh/tidb/stable/explain-overview算子的执行顺序
算子的结构是树状的,但在查询执行过程中,并不严格要求子节点任务在父节点之前完成。TiDB 支持同一查询内的并行处理,即子节点“流入”父节点。父节点、子节点和同级节点可能并行执行查询的一部分。
在以上示例中,├─IndexRangeScan_8(Build) 算子为 a(a) 索引所匹配的行查找内部 RowID。└─TableRowIDScan_9(Probe) 算子随后从表中检索这些行。
Build 总是先于 Probe 执行,并且 Build 总是出现在 Probe 前面。即如果一个算子有多个子节点,子节点 ID 后面有 Build 关键字的算子总是先于有 Probe 关键字的算子执行。TiDB 在展现执行计划的时候,Build 端总是第一个出现,接着才是 Probe 端。
执行计划很多都是循环执行的,虽然有顺序但其实是按顺序动态循环执行的,tidb中的loops就是循环调用次数的意思
这个sql就是执行了87.7ms
缩进一样的先执行上面的,缩进不一样的执行缩进多的