分区表动态裁剪模式问题

【TiDB 使用环境】生产环境
【TiDB 版本】8.5.2
【操作系统】
【部署方式】机器部署(三台96C 512G 6T NvmeSSD机器混部 )
【集群数据量】1T
【集群节点数】3pd+3db+6kv
【问题复现路径】
【遇到的问题:问题现象及影响】
tidb从v6.3.0 开始,分区动态裁剪默认使用 dynamic模式,按理说默认的dynamic模式性能会更好,但是实际使用过程中同一张表的同一个sql使用dynamic和 static模式sql执行耗时差异特别大,
dynamic 10S
static 0.01S
【资源配置】

【复制黏贴 ERROR 报错的日志】
【其他附件:截图/日志/监控】

表中1千万数据,三百个分片
ddl(省略了部分字段)

查询sql语句

sql执行情况

表的健康100

static模式执行计划
默认每个分区全分区扫(有索引没命中)

dynamic模式执行计划

会不会是统计信息不准确

表的健康度,和执行计划看起来都没啥问题呢

show stats_meta where table_name like “seed_report”;
看下表的分区统计信息,把global和p190-199这些分区的内容截出来

大概率是统计信息不准确,建议可以考虑下面操作。

1、查看当前统计信息是否健康
SHOW STATS_HEALTHY WHERE Db_name=‘seed_report’ AND Table_name=‘dw_seed_user_task_…’;

2、更新统计信息
ANALYZE TABLE dw_seed_user_task_…;

查询前执行过更新统计信息,确认执行前后表的健康度都是100,

结果如下
状态信息结果.xlsx (13.2 KB)

看大佬们讨论问题

提供一下执行计划的完整内容吧

完整执行计划
执行计划-静态裁剪.xlsx (7.3 KB)
执行计划-动态裁剪.xlsx (4.0 KB)

看了你提供的结果,确实统计信息不一致,建议重建统计信息。

1、删除现有统计信息
DROP STATS dw_seed_user_task_group_percent;

2、重新分析整表
ANALYZE TABLE dw_seed_user_task_group_percent;

重建会消耗资源,建议业务低峰期在执行!!!

看统计信息和执行计划,静态分区裁剪和动态分区裁剪其实最大的区别是静态分区裁剪没有用到idx_pid_cid_did_sid索引,而动态分区裁剪用到了,实际来看,使用idx_pid_cid_did_sid索引,预计从899933.81行数据中可通过索引过滤出75760.52,但是实际索引执行,是从954280中过滤出了954280行数据,从你的统计信息中看,p190到199,实际才95W的数据,索引过滤出95W数据,那不是全部过滤出来了,然后还要回表?还不是不如全表扫了还。
我的建议是,你直接还是使用动态分区裁剪,通过hint指定不使用索引idx_pid_cid_did_sid,看下新sql的执行计划,是不是会变快即可。
SELECT /*+ IGNORE INDEX(idx_pid_cid_did_sid) / …
FROM dw_seed_user_task_group_percent
WHERE …;
或者直接指定全表扫
SELECT /
+ USE INDEX() */

FROM dw_seed_user_task_group_percent
WHERE …;

执行计划看统计信息是正确的,没有用到索引,索引创建正确吗?强制索引后,执行计划怎样的

确实,指定不使用索引执行耗时和静态基本一致

哈哈,这个耗时长就是因为使用了索引导致的,楼上有解释

索引的统计信息应该不准吧?从分区的统计信息看,数量和执行计划显示的差不多,动态裁剪的那个显示,扫描后的数据量预估只有7万,但索引扫描的动作,条件中只有分区的条件,无其他条件,按理说这个预估数据量应该=分区数据量总和
ge(seed_report.dw_seed_user_task_group_percent.province_shard_id, 190), le(seed_report.dw_seed_user_task_group_percent.province_shard_id, 199)

数据库设计感觉也可以考虑这种情况的优化:索引扫描只有分区条件,而且也需要回表,这种情况应该考虑改分区扫描

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。