tidb 优化器bug???

为提高效率,请提供以下信息,问题描述清晰能够更快得到解决:
【 TiDB 使用环境】
v5.0.6

【概述】 场景 + 问题概述

【背景】 做过哪些操作

【现象】 业务和数据库现象

【问题】 当前遇到的问题

【业务影响】

【TiDB 版本】 v5.0.6

【应用软件及版本】

【附件】 相关日志及配置信息

  • TiUP Cluster Display 信息
  • TiUP CLuster Edit config 信息

监控(https://metricstool.pingcap.com/)

  • TiDB-Overview Grafana监控
  • TiDB Grafana 监控
  • TiKV Grafana 监控
  • PD Grafana 监控
  • 对应模块日志(包含问题前后 1 小时日志)

表信息如下
image

正常sql


使用limit


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

2 个赞

sql 带limit 索引选择错误

程序使用 FORCE INDEX (i_CreateTime) 解决

1 个赞

1.麻烦看下表和索引的统计信息健康度分数,如果分数很低的话,优化器有可能会错误估算了成本,可以重新收集下统计信息;
2.如果表和索引健康度得分都很高的话,麻烦反馈下两种查询的真实执行计划(即 explain analyze + SQL )、完整的表结构,并导出下表的统计信息,参考:https://docs.pingcap.com/zh/tidb/v5.0/statistics#导出统计信息

1 个赞

健康度 (27.3 KB) train_order_info (6.8 MB)

健康度 包含了 统计信息等内容。和执行计划。
导出统计信息的是 train_order_info 文件

附件中的执行计划在没有使用 force index 时走的是 i_env 索引,并不是上面的 i_order_state 索引,强制后会走到i_createTime索引,结合表的健康度得分并不高来看,推测是i_createTime` 统计信息不准确导致优化器选错了索引,建议重新收集下该索引的统计信息,再看下效果。

重新收集后


重新收集后 explain analyze 还是选错索引吗?如果是的话麻烦把最新的统计信息也导出一份吧 ,多谢

train_order_info (6.9 MB)

从统计信息直方图信息中看,字段 order_state = 1 并没有落在桶的范围内,感觉是这里的问题导致优化器认为走索 i_order_state 成本更低:

有什么办法可以搞一下嘛,我手动收集一下 直方图信息?

先全表收集下统计信息,如果还有问题需要再进一步分析。

生产环境,可以定期收集统计信息进行健康检查

大佬,请教几个问题
1、我按前面提供的导出统计信息导入后分别为train_order_info和train_order_info1 为啥stats_bucket里没有order_state列的信息,只有索引i_order_state列的信息(重新建表然后load stats试了多次,5.2.1版本)

2、 ‘ 字段 order_state = 1 并没有落在桶的范围内’ 这个是统计信息收集的问题造成的遗漏还是因为收集统计信息时表内没有order_state = 1的记录

3、如果stats_buckes里没有相应字段的记录话优化器默认使用什么样的值?

show stats_buckets/stats_histograms 只会显示加载到内存中的统计信息。对于列的统计信息,当有查询涉及到该列时,tidb 才会将该列的统计信息加载到内存中,这时候才能看到,索引的统计信息是常驻内存的,show stats_* 总是能看到索引的统计信息;
所以你可以先执行下如下的 SQL:
SELECT id, order_serial_no FROM train_order_info FORCE INDEX (`i_CreateTime`) WHERE order_state = 1 AND CreateTime > DATE_SUB(now(), INTERVAL 6 DAY) AND env = 'prod' AND gmt_pay_out < now() AND id > 0 ORDER BY id ASC LIMIT 0, 100;
执行完成后再次查询 show stats_buckets 应该就可以看到字段 order_state 的信息了。

感谢!还请教下内存没有的话可以直接通过mysql.stats_buckets来查询全部的列信息吧?但是里面怎么和列信息关联呢?
image

系统表 stats_histograms 中当字段 is_index 值为 0 时,字段 hist_id 即为 column_id,当字段 is_index 值为 1 时,字段 hist_id 即为 index_id ,但比较尴尬的是貌似没法直接查询 colunmd_idcolumn_name 的对应关系,在系统表 information_schema.columns 中没有这种对应 :upside_down_face:

感谢,隐藏属性太多了,这些内容建议官网写下,否则大家都不知道

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