OceanBase 查询优化器排障手册:慢 SQL 定位、行为追踪与参数调优

发布时间:2026/9/17 8:20:40
OceanBase 查询优化器排障手册:慢 SQL 定位、行为追踪与参数调优 OceanBase 查询优化器排障手册慢 SQL 定位、行为追踪与参数调优【免费下载链接】oceanbaseOceanBase is the unified distributed database for the AI era — open-source, multi-model, one engine for your most demanding workloads.项目地址: https://gitcode.com/GitHub_Trending/oc/oceanbase这篇文章写给在 OceanBase 上遇到过SQL 突然变慢的 DBA 和后端开发。它从一个生产慢查询场景切入讲清如何开启优化器行为记录optimizer_trace、读懂其中的关键段落再用几张参数表把连接顺序和转换策略调回合理状态。读完之后你可以独立完成复现—定位—调参—验证的排查闭环。当一条 SQL 从 100ms 涨到 10 秒假设线上某查询平时 100 毫秒内返回某天早上开始稳定跑到十秒。先做减法排除锁等待、资源打满等外部因素后用执行计划做一次前后对比。如果计划本身变了——比如从索引扫描退化成了全表扫描、表连接顺序换掉了——问题大概率出在优化器的决策上。此时光看EXPLAIN的输出不够你需要优化器脑子里的完整推演过程。一行 SQL 打开优化器的黑匣子OceanBase 把这一组开关做成了 MySQL 兼容的系统变量定义集中在 系统变量初始化文件。核心变量如下变量作用说明optimizer_trace记录总开关设为enabledon后当前会话开始记录optimizer_trace_features记录范围限定只追踪特定优化特征optimizer_trace_limit记录条数上限默认 1optimizer_trace_max_mem_size记录内存上限默认 16384大查询可适当调大optimizer_trace_offset分页偏移默认 -1从第一条开始读-- 为当前会话打开优化器记录 SET optimizer_trace enabledon; -- 限制记录条数与内存占用防止刷爆会话 SET optimizer_trace_limit 100; SET optimizer_trace_max_mem_size 16384;读跟踪日志先看哪几处变量设好后把慢 SQL 原样执行一遍再从信息模式表里把记录捞出来-- 查看上一条 SQL 的优化器跟踪内容 SELECT * FROM information_schema.optimizer_trace\G跟踪内容由 跟踪实现头文件 中的ObOptimizerTraceImpl逐段写入阅读时建议按这个顺序环境参数段确认会话实际生效的优化器参数排除设了变量却没生效的乌龙。转换段谓词下推、子查询展开等规则在这里留痕。规则没命中时这一段能直接告诉你卡在哪。代价评估段各候选路径的估行数和打分结果行数估算偏差大的问题通常在这一段暴露。调连接顺序与转换策略一张参数清单定位到原因后大部分情况用下面几个变量就能把行为掰回来。完整规则实现位于 优化器源码目录这里只列日常会用到的变量作用默认值 / 建议_optimizer_cost_based_transformation代价转换策略0 禁用、1 基础、2 全开默认 1怀疑转换引入坏计划时改 0 对比_join_order_enum_threshold连接顺序枚举算法选择的表数阈值默认 10三表以上连接不佳时可上调_optimizer_max_permutations单次枚举允许的最大连接排列数默认 2000枚举被截断时调大enable_optimizer_rowgoal估计时是否考虑 LIMIT 等行数目标枚举型 OFF/AUTO/ON默认 AUTO-- 放宽多表连接的枚举阈值随后用 EXPLAIN 验证计划变化 SET _join_order_enum_threshold 15; EXPLAIN SELECT * FROM o JOIN c ON o.cid c.id WHERE o.amount 100;参数调完只是第一步。更稳的两种手段用 Hint 直接指定访问路径把风险从全局参数降级到单条 SQL或者先刷新统计信息让优化器自己选对。-- 用 Hint 强制走索引绕过优化器的选择 SELECT /* INDEX(o idx_order_date) */ * FROM order_table o WHERE o.order_date 2023-01-01;-- 统计信息过期时先刷新再观察计划是否自愈 ANALYZE TABLE order_table COMPUTE STATISTICS;常见坑与解法坑现象可能原因处理办法明明有索引却走全表扫描统计信息过期或谓词选择性不划算先ANALYZE TABLE确认代价合理后用 INDEX Hint 兜底估行数和实际差几个数量级表从未收集统计命中默认估算值收集统计后重跑并在跟踪日志代价段复核估行来源连接顺序不达标枚举空间被阈值截断选了次优解上调_join_order_enum_threshold必要时放大_optimizer_max_permutations跟踪表查出来是空的会话断开后重连、变量没带上在同一会话内先设变量再执行 SQL检查optimizer_trace_limit是否为 0更细的日志等级配置可以配合 日志配置文档 一起使用观察优化器之外的执行侧细节。计划回到合理状态后记得把临时改大的枚举参数还原避免复杂查询的编译耗时被放大。下一步建议挑一条当前最慢的生产 SQL把跟踪日志里转换段和代价段各截一份存档以后同类问题再出现时直接对比即可。【免费下载链接】oceanbaseOceanBase is the unified distributed database for the AI era — open-source, multi-model, one engine for your most demanding workloads.项目地址: https://gitcode.com/GitHub_Trending/oc/oceanbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考