TiDB 执行计划走偏的问题大家遇到过吗?MySQL 里好好的索引,到 TiDB 就不走了,加了 USE INDEX 强行指定才正常,这是统计信息不准还是优化器有 bug?ANALYZE 完还是一样。
TiDB 执行计划走偏的问题大家遇到过吗?MySQL 里好好的索引,到 TiDB 就不走了,加了 USE INDEX 强行指定才正常,这是统计信息不准还是优化器有 bug?ANALYZE 完还是一样。
执行计划走偏,ANALYZE 后也无效,除了统计信息,很可能还与 TiDB 的代价估算逻辑有关。
这里是几种排错和解决思路:
诊断问题:ANALYZE 后若健康度接近 100%,可能和行数估算有关。一种有效方法是使用 EXPLAIN ANALYZE 查看各步骤实际和预估的行数。
指定索引 (临时恢复):立即生效,可防止误用索引。可使用 SQL HINT (/*+ USE_INDEX(table_name, index_name) */) 或 MySQL 兼容语法 USE INDEX (index_name)。
绑定执行计划 (治本):最适合长期稳定地固定计划,无需改代码。通过**SQL Plan Management (SPM)创建执行计划绑定,强制稳定执行路径。
调整优化器行为:更细粒度地控制行为。新(v6.5.3+)可通过 tidb_opt_fix_control 变量控制。旧版可调整直方图相关参数。
版本升级:未明确提及,但鉴于修复持续进行,升级到最新稳定版可作为兜底方案。
有可能是bug,绑定执行计划吧。
mysql 没有统计信息这样功能,统计信息是oracle 。你可以用查lift JION on 来调整查询
热点Region本质是数据分布不均,AUTO_RANDOM是缓解手段。
使用的哪个版本,低版本的有bug
使用EXPLAIN ANALYZE对比查询预估行数与实际行数,定位行数估算不准的环节,确认问题根源。
有些低版本存在优化器相关 Bug。
ANALYZE 采集的采样分布、行数预估偏差,TiDB 对范围条件、等值匹配的行数计算逻辑和 MySQL 不一样
大量迁移 MySQL 到 TiDB 的 DBA 都会遇到MySQL 正常走索引、TiDB ANALYZE 后仍不走索引,强制 USE INDEX 才生效,绝大多数不是优化器 Bug,是 TiDB 分布式成本模型、统计估算机制、下推规则和 MySQL 完全不同;只有极少数边缘场景才是优化器逻辑缺陷。
核心原因是TiDB 统计信息、代价模型和 MySQL 差异大,ANALYZE 无效多是直方图 / 采样问题,并非单纯优化器 bug
大概率不是优化器 bug,核心是 TiDB 与 MySQL 代价模型、索引扫描开销计算逻辑差异,ANALYZE 仅缓解统计不准,无法抹平底层 IO 估算差值。
常见是统计/代价模型差异,不完全是 bug。核对列NDV、健康度;可调优化器变量或绑定计划。持续走偏再提官方 issue 并附计划与stats。
我6.5.0也有类似问题,后续绑定执行计划好了
学习了
两大主因:统计失真 VS 优化器 / 架构差异
1. 统计信息不准(ANALYZE 普通执行修复不了,你大概率没做全量分析)
TiDB 统计依赖直方图、NDV 唯一值基数估算扫描行数,一旦估算行数偏差巨大,优化器会误判索引代价更高,直接选全表; 普通 ANALYZE TABLE t 是采样分析,数据倾斜、海量分区、字符串列极易失真,执行完依旧选错索引
TiDB 和 MySQL 机制天生不同
一般是统计信息不准–这个可以使用analyze 去重新收集统计信息,第二种可能就是有bug了,需要手动使用binding将对应sql绑定到你希望的执行计划
分布式代价计算逻辑和 MySQL 不同。
用EXPLAIN ANALYZE 定位偏差;高采样率重采统计;临时用索引 hint,长期 SPM 绑定执行计划。