写点什么

YashanDB|执行计划突然变差? 小心统计信息时间戳不一致!

作者:数据库砖家
  • 2025-04-30
    广东
  • 本文字数:909 字

    阅读完需:约 3 分钟

某局点在使用 YashanDB 时,出现了 CPU 长时间 100% 的情况,业务受影响严重。经过分析发现,根源是某些 SQL 执行计划发生变化,背后竟是统计信息中的 analyze time 不一致惹的祸!

一、问题现象

系统负载飙升,数据库 CPU 占用持续 100%;

检查发现多个 SQL 性能异常,其中一个简单的“单行绑定 + 排序”语句变得非常慢;

执行计划发生变化,选用了性能较差的索引路径。

二、风险与影响

SQL 执行时间异常,影响正常业务响应;

操作系统负载升高,可能引发数据库或服务宕机;

计划选择错误,严重时可能导致全表扫描等高开销操作。

三、问题影响版本

经确认,该问题出现在 YashanDB 22.2.10.100 版本中。

四、问题根本原因分析

进一步分析后发现,问题的关键在于:

hist_head$ 表中列的 analyze time 早于 tab$ 表中的 analyze time

这会导致优化器在调用 estColEqualOrNotParam 方法时:

尝试加载列统计信息;

由于 colStats = null,无法使用真实选择性;

系统自动使用默认 selectivity 值(0.04)进行估算;

实际上该列选择性极好,仅为 0.00003;

导致估算结果失真,从而选用了错误的索引。

示意图

五、处理方式与规避建议

在现网中,客户通过将错误索引设为 invisible,成功规避了错误执行计划。

推荐做法:

使用 alter index xxx invisible; 隐藏问题索引;

或者刷新列统计信息,确保 hist_head$ 与 tab$ 中时间一致;

日常维护中关注统计信息更新时间,避免残留旧数据干扰优化器判断。

六、问题排查与处理过程回顾

观察到 SQL 执行计划中,sub_account_id 的选择性非常低(实际数据分布极稀疏);

表数据量 6000 万,distinct 约 200 万,选择性应接近 0.00003;

但优化器使用默认 0.04.误判过滤效果,导致执行计划“跑偏”;

正确的执行计划 rows 估算值更接近实际数据分布,性能显著提升。

七、知识点补充

hist_head$:存放列的通用统计信息;

histgrm$:用于存放列的直方图数据(分布式信息);

优化器判断执行路径时优先参考这些表中的统计信息;

时间戳不一致,会导致优化器忽略某些信息,使用默认值。

八、总结建议

建议在收集统计信息时全表统一分析,避免局部更新留下时间戳差异;

运维过程中定期核查 tab$ 与 hist_head$ 中 analyze time 是否对齐;

如发现执行计划“突然变差”,可从统计信息完整性优先排查。

用户头像

还未添加个人签名 2025-04-09 加入

还未添加个人简介

评论

发布
暂无评论
YashanDB|执行计划突然变差?小心统计信息时间戳不一致!_数据库_数据库砖家_InfoQ写作社区