order by和group by或者distinct组合使用不可下推计算么。

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:

【TiDB 版本】
4.0.11
【问题描述】
比如下面sql 发现无法下推到tikv上直接计算。group 和 TopN 都是在tidb计算的。

SET @@session.tidb_opt_distinct_agg_push_down = 1;
select  * from table a GROUP BY a.aid ORDER BY create_time  DESC limit 10;

若提问为性能优化、故障排查类问题,请下载脚本运行。终端输出的打印结果,请务必全选并复制粘贴上传。

  1. SQL 执行计划是怎样的?提供一下 explain analyze select * from table a GROUP BY a.aid ORDER BY create_time DESC limit 10; 的完整信息。
  2. 也提供一下表结构,show create table a 的结果。
CREATE TABLE `video_auto` (
  `id` bigint(12) NOT NULL AUTO_INCREMENT,
  `video_id` bigint(12) NOT NULL COMMENT '视频id',
  `brand_id` bigint(20) DEFAULT NULL COMMENT '品牌id',
  `series_id` bigint(20) DEFAULT NULL COMMENT '车系id',
  `score` float DEFAULT NULL COMMENT '相关度',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_del` tinyint(3) NOT NULL DEFAULT '0' COMMENT '状态 0 正常 1 删除',
  PRIMARY KEY (`id`),
  KEY `idx_auto_video_id` (`video_id`),
  KEY `idx_auto_brand_id` (`brand_id`),
  KEY `idx_auto_series_id` (`series_id`),
  KEY `IDX_brand_id_is_del` (`brand_id`,`is_del`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=386273;
select id from video_auto GROUP BY video_id ORDER BY create_time  DESC limit 10 ;
Projection_8	10.00	10	root		time:558.3ms, loops:2, Concurrency:OFF	svda.video_auto.id	744 Bytes	N/A
└─TopN_11	10.00	10	root		time:558.3ms, loops:2	svda.video_auto.create_time:desc, offset:0, count:10	27.7 KB	N/A
  └─HashAgg_21	129367.61	129312	root		time:550.3ms, loops:129, PartialConcurrency:4, FinalConcurrency:4	group by:svda.video_auto.video_id, funcs:firstrow(Column#10)->svda.video_auto.id, funcs:firstrow(Column#11)->svda.video_auto.create_time	3.01 MB	N/A
    └─TableReader_22	129367.61	129312	root		time:263.3ms, loops:2, cop_task: {num: 1, max: 263.2ms, proc_keys: 267001, tot_proc: 236ms, rpc_num: 1, rpc_time: 263.2ms, copr_cache: disabled}	data:HashAgg_15	2.96 MB	N/A
      └─HashAgg_15	129367.61	129312	cop[tikv]		tikv_task:{time:231ms, loops:261}	group by:svda.video_auto.video_id, funcs:firstrow(svda.video_auto.id)->Column#10, funcs:firstrow(svda.video_auto.create_time)->Column#11	N/A	N/A
        └─TableFullScan_20	266941.00	267001	cop[tikv]	table:video_auto	tikv_task:{time:151ms, loops:261}	keep order:false	N/A	N/A

是因为 GROUP BY的字段分散在多个region上所以还是去要拿回tidb聚合么

聚合看起来已经下推,需要在 tidb 层做一个二次聚合然后 top N 截取

我这里看tidb_opt_distinct_agg_push_down 0或1 actRow返回tidb的条数是一样的。

这个和 tidb_opt_distinct_agg_push_down 这个开启无关。HashAgg_15 是已经下推到 TiKV ,做第一次聚合。由于 TiKV 这边的数据是以 Region 为单位,把数据打散分布在多台机器上的。所以有可能出现同一个 video_id 以及 create_time 在不同的 region 以及不同的机器上面的情况。所以需要在 TiDB 层再进行一次聚合才能得到最终的结果,并且这边 order by create_time 所以也不能直接走 idx_auto_video_id 这个索引获取数据并忽略排序,还是需要在 TiDB 聚合结果之后再进行根据 create_time 排序得到最终的 10 行结果。

明白了