暂无图片
暂无图片
6
暂无图片
暂无图片
暂无图片

一次典型的 SQL 性能问题排查:临时表导致的隐藏性能陷阱

在日常数据库运维过程中,经常会遇到这样一类问题:

数据库整体性能正常,但某一条 SQL 在业务系统中执行极慢,
然而 DBA 在后台手工执行时,却发现 执行速度非常快。

这类问题往往不在“数据库整体性能”,而隐藏在具体 SQL 的执行细节和业务执行环境差异中。

本文记录了一次真实的 SQL 性能排查过程,最终定位到 临时表使用不当 所引发的问题。

一、问题现象:整体正常,单条 SQL 异常

客户业务系统运行过程中,出现如下现象:
• 数据库整体运行状态正常
• CPU、IO、等待事件均无明显异常
• 仅有 一条业务 SQL 在前台执行非常缓慢
• 同一条 SQL 在后台手工执行时,执行速度却非常快

从表象来看,这并不像是数据库整体性能瓶颈,更像是某条 SQL 在特定执行场景下存在问题。

二、通过 AWR 报告定位性能热点

为进一步确认问题,通过 AWR 报告(使用 @?/rdbms/admin/awrrpti.sql 生成)对系统性能进行分析。
43c291d0d72d3220f471c0db902b1bb6.png
AWR 报告显示:
• 系统的主要性能消耗集中在 一条 SQL
• 该 SQL 单次执行时间约为 406,814 ms

从执行时间来看,这条 SQL 明显是当前系统的主要性能瓶颈。
image.png

三、执行计划“完美”,却解释不了慢的问题

继续查看该 SQL 的执行计划,发现一个容易让人放松警惕的情况:
• 执行计划 cost 不大
• 各个执行步骤看起来都非常合理
• 没有明显的全表扫描或低效访问路径

从执行计划角度判断,这条 SQL 理论上不应该这么慢。
image.png
但事实是:
image.png
SQL 确实执行得非常慢。

四、执行统计信息暴露异常:buffer gets 极高

在进一步查看 SQL 的执行统计信息后,问题开始显现出来。

该 SQL 的统计信息显示:
• buffer gets 达到 595,764,242
• 这是一个极不正常的数值

而从数据规模来看:
• SQL 中涉及的最大表 GL_VERIFY_LOG 只有 17,710 行
• 其他表的数据量更是可以忽略不计

在如此小的数据规模下,却出现如此高的 buffer gets,显然不符合正常逻辑。

五、常规思路排查:统计信息并非根因

第一反应自然是怀疑:

是否因为对象统计信息不准确,导致优化器判断失误?

于是对 SQL 涉及的所有对象进行了 100% 采样的统计信息收集。

但结果是:
• SQL 执行性能没有任何改善
• buffer gets 依然很高

同时可以确认:
• SQL 未使用绑定变量
• 不存在 bind peeking 导致的执行计划不稳定问题
• 后台执行时显示的执行计划,与 AWR 中的执行计划一致

此时,执行计划、统计信息、SQL 写法,似乎都“没有问题”。

六、关键细节:执行计划中的 Dynamic Sampling

在反复对比前台与后台执行差异时,注意到一个细节:

后台执行该 SQL 时,执行计划中出现了 Dynamic Sampling(动态采样)。
image.png
这是一个非常关键的信号。

在 Oracle 中,涉及临时表的 SQL,往往会触发动态采样,以便在运行时获取更准确的数据分布信息。

这一现象直接将排查方向指向了 SQL 中可能存在的临时表。

七、问题根因确认:临时表数据量差异

继续深入检查 SQL 涉及的对象,最终确认:
• SQL 中使用了临时表 ASSTEMPORA
• 前台业务程序执行 SQL 前,会向该临时表中加载 大量数据
• 后台 DBA 手工执行 SQL 时,该临时表 数据为空

这就解释了所有现象:
• 前台执行:
• 临时表数据量大
• SQL 执行过程中产生大量 buffer gets
• 导致执行时间极长
• 后台执行:
• 临时表无数据
• SQL 执行路径看起来“非常理想”
• 执行时间极短

八、优化方案:为临时表补充索引

问题的本质在于:

临时表在高数据量参与 SQL 计算时,缺失必要索引。

针对该问题,在临时表 ASSTEMPORA 上创建索引:

CREATE INDEX ASSTEMPORA_IDX ON ASSTEMPORA (assid);

索引创建完成后:
• 前台 SQL 执行时间明显缩短
• buffer gets 大幅下降
• 业务模块性能恢复正常

问题得到彻底解决。

九、小结:临时表同样需要“正式对待”

通过这次问题排查,可以得到几个非常重要的经验结论:
1. 执行计划看起来没问题,并不代表 SQL 一定高效
2. 前台与后台执行差异,往往来自 数据状态不同
3. 临时表一旦承载真实业务数据,就必须像普通表一样设计索引
4. 执行计划中的 Dynamic Sampling 是一个非常重要的排查线索

很多 SQL 性能问题,并不是写得复杂,而是在真实业务场景下,被放大了原本被忽略的设计缺陷。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论