TopN 算子中的actrows 疑问

版本是6.5.3
数据来源于tpch

sql语句:
 explain analyze select * from  orders where O_TOTALPRICE >=370000 order by O_ORDERDATE  asc limit 500,10;

对于执行计划中下推到tikv算子的TopN算子的actrows 为什么是6099 ? 这一点不是很懂,麻烦请老师解答下

mysql> explain analyze select * from  orders where O_TOTALPRICE >=370000 order by O_ORDERDATE  asc limit 500,10;
+----------------------------------+----------+---------+-----------+------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------+------+
| id                               | estRows  | actRows | task      | access object                                        | execution info                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | operator info                                  | memory   | disk |
+----------------------------------+----------+---------+-----------+------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------+------+
| TopN_9                           | 10.00    | 10      | root      |                                                      | time:99.5ms, loops:2                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       | tpch2.orders.o_orderdate, offset:500, count:10 | 307.6 KB | N/A  |
| └─IndexLookUp_22                 | 510.00   | 6099    | root      |                                                      | time:97.9ms, loops:8, index_task: {total_time: 38ms, fetch_handle: 38ms, build: 6.63µs, wait: 6.81µs}, table_task: {total_time: 151.3ms, num: 5, concurrency: 5}, next: {wait_index: 3.64ms, wait_table_lookup_build: 231.9µs, wait_table_lookup_resp: 92.3ms}                                                                                                                                                                                                                                                                             |                                                | 1.31 MB  | N/A  |
|   ├─IndexRangeScan_19(Build)     | 14966.40 | 11447   | cop[tikv] | table:orders, index:index_O_TOTALPRICE(O_TOTALPRICE) | time:37.6ms, loops:15, cop_task: {num: 7, max: 12.9ms, min: 983.4µs, avg: 5.69ms, p95: 12.9ms, max_proc_keys: 4695, p95_proc_keys: 4695, tot_proc: 2ms, tot_wait: 4ms, rpc_num: 7, rpc_time: 39.6ms, copr_cache: disabled, distsql_concurrency: 15}, tikv_task:{proc max:2ms, min:0s, avg: 714.3µs, p80:1ms, p95:2ms, iters:35, tasks:7}, scan_detail: {total_process_keys: 11447, total_process_keys_size: 526562, total_keys: 11454, get_snapshot_time: 2.47ms, rocksdb: {key_skipped_count: 11447, block: {cache_hit_count: 56}}}       | range:[370000.00,+inf], keep order:false       | N/A      | N/A  |
|   └─TopN_21(Probe)               | 510.00   | 6099    | cop[tikv] |                                                      | time:146.1ms, loops:13, cop_task: {num: 15, max: 57ms, min: 5.8ms, avg: 22.7ms, p95: 57ms, max_proc_keys: 1967, p95_proc_keys: 1967, tot_proc: 150ms, tot_wait: 19ms, rpc_num: 15, rpc_time: 340.6ms, copr_cache: disabled, distsql_concurrency: 15}, tikv_task:{proc max:36ms, min:2ms, avg: 10.5ms, p80:25ms, p95:36ms, iters:19, tasks:15}, scan_detail: {total_process_keys: 11447, total_process_keys_size: 1732802, total_keys: 11463, get_snapshot_time: 7.62ms, rocksdb: {key_skipped_count: 32, block: {cache_hit_count: 42082}}} | tpch2.orders.o_orderdate, offset:0, count:510  | N/A      | N/A  |
|     └─TableRowIDScan_20          | 14966.40 | 11447   | cop[tikv] | table:orders                                         | tikv_task:{proc max:34ms, min:2ms, avg: 9.8ms, p80:24ms, p95:34ms, iters:19, tasks:15}                                                                                                                                                                                                                                                                                                                                                                                                                                                     | keep order:false                               | N/A      | N/A  |
+----------------------------------+----------+---------+-----------+------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------------------------------+----------+------+
5 rows in set (0.11 sec)

表结构

mysql> show create table orders;
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| orders | CREATE TABLE `orders` (
  `O_ORDERKEY` bigint(20) NOT NULL,
  `O_CUSTKEY` bigint(20) NOT NULL,
  `O_ORDERSTATUS` char(1) NOT NULL,
  `O_TOTALPRICE` decimal(15,2) NOT NULL,
  `O_ORDERDATE` date NOT NULL,
  `O_ORDERPRIORITY` char(15) NOT NULL,
  `O_CLERK` char(15) NOT NULL,
  `O_SHIPPRIORITY` bigint(20) NOT NULL,
  `O_COMMENT` varchar(79) NOT NULL,
  PRIMARY KEY (`O_ORDERKEY`) /*T![clustered_index] CLUSTERED */,
  KEY `index_O_TOTALPRICE` (`O_TOTALPRICE`),
  KEY `index_a` (`O_ORDERSTATUS`,`O_TOTALPRICE`),
  KEY `indexO_CUSTKEY` (`O_CUSTKEY`),
  KEY `index_date` (`O_ORDERDATE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |
+--------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

如果估计值与实际值显著不同,那么应考虑在受影响的表上运行 ANALYZE TABLE

{total_process_keys: 11447, 
total_process_keys_size: 1732802,
 total_keys: 11463, get_snapshot_time: 7.62ms,
 rocksdb: {key_skipped_count: 32, block: {cache_hit_count: 42082}}} | tpch2.orders.o_orderdate, offset:0, count:510  | N/A      | N/A  |
total_process_keys: 11447, total_process_keys_size: 526562, total_keys: 11454

这个表是不是做了很多删除?查下这个表的健康度

topn下推到tikv,符合条件的数据回表时每个cop task上做topn ,总共15个,按照limit条件要扫描510条,但每个cop 扫描时不一定就能达到510条,比如某个region只有 490条符合条件的数据,这些数据返回tidb再次排序后最终返回10条

1 个赞

执行TopN时根据实际的执行计划可以看到Coprocessors 的并行算子distsql_concurrency是15,limit 500,10这里写明了每个算子会扫描510行,估算时预估是扫描一次,但是实际执行时要考虑多并发执行即15×510=7650行。在实际操作过程当中,其中某些算子扫描的数据范围可能会有不同,增多(有历史已删除的数据)或减少(算子扫描数据范围不足510行)。

只要实际的扫描行数差别不大,就认为执行计划没问题。

1 个赞

某些算子扫描的数据范围可能会有不同,增多(有历史已删除的数据)
扫描到的历史版本数据会算到执行计划里面的actRows 里面嘛?

这个回复有误,请忽略

扫描到的历史版本数据是不会算到执行计划里面的actRows 里面的

元旦快乐

评估与实际是不一样 的

请问这里为什么是15呢?这个15是怎么算出来的


执行计划中一个loops 15一个loops13这个又是为什么?

执行计划里有这个 cop_task num 次数标识

这个表符合条件的region分布在15个节点上,所以并发是15?

image
每个算子的cop task数量,一个cop task 扫描一个region , 并发多少个是concurrency 相关变量设置,默认15

2 个赞

执行计划中的 loops 是表示当前算子被父算子调用的次数,所以

  • 执行计划中的 loops 15,表示算子IndexRangeScan_19(Build) 被父算子 IndexLookUp_22 调用了 15 次。
  • 执行计划中的 loops13,表示算子 TopN_21(Probe) 被父算子 IndexLookUp_22 调用了 13 次。

扫描数据 Region 是通过 Cop Task 任务来完成的,一次task扫描一个 Region, cop task 中的 num 表示 Task 的数量。“loops:13, cop_task: {num: 15, ” 这里的“num: 15” 就表示扫描 15 个 Region。前面我提到的用 distsql_concurrency 来估计计算并不准确,它是Coprocessors扫描 Region内的并发数,和这个无关。

另外,查看执行计划时也可以重点关注一下算子的执行时间。即 execution info 中的 time,它表示从进入算子到离开算子的全部执行时间,如果该算子被父算子多次调用 (loops),这个时间就是累积的总时间。可以通过它确认某个环节慢的问题,是性能分析时的关键指标之一。

2 个赞

所以上面的表扫描的region有15个以上,如果低于15个region,实际cop_task的个数是怎样的?

是正好赶上有15个region了,有多人要扫描的region就有多少cop task ,你可以看看一个大表全扫的 一个只查一行数据的计划

1 个赞