度量Exadata上Oracle查询性能时如何排除缓存影响
Exadata平台Oracle查询性能测试规避缓存干扰方案
核心问题定位
- 你的执行计划中未出现
RESULT CACHE行,直接证明当前查询完全没有触发Oracle结果缓存机制。这就是你添加/*+ NO_RESULT_CACHE */提示后查询耗时无任何变化的根本原因——该提示仅对已经触发结果缓存的查询生效,你的查询本来就没走结果缓存,加提示自然不会产生效果,不存在提示使用方式错误的问题。
触发结果缓存的执行计划会出现专门的RESULT CACHE条目,示例如下:-------------------------------------------------------------- | Id | Operation | Name |Rows -------------------------------------------------------------- | 0 | SELECT STATEMENT | | 11 | 1 | RESULT CACHE | 8fpza04gtwsfr6n595au15yj4y | | 2 | HASH GROUP BY | | 11 | 3 | TABLE ACCESS FULL| EMPLOYEES | 107 -------------------------------------------------------------- - 你之前的方案存在认知偏差:你查阅的结果缓存相关文档,仅覆盖了Oracle三类核心缓存中占比最低的一类,根本无法解决缓存导致的性能虚高问题。Oracle会影响查询性能的缓存共三类:
- 结果缓存(Result Cache):存储查询最终结果集,仅当执行计划出现
RESULT CACHE条目时生效,默认配置下绝大多数普通查询不会自动触发该缓存,仅在手动添加结果缓存提示、开启实例级强制结果缓存参数、查询对象标记为默认结果缓存时才会启用。 - 数据块缓存(Buffer Cache):存储从存储读取到内存的数据块,是导致重复查询性能虚高的最主要原因——第一次查询将数据块读入内存后,后续查询不需要再和存储交互直接读内存,性能通常比冷启动高几倍到几十倍。
- 共享池缓存(Shared Pool):存储SQL解析后的执行计划、游标信息,避免重复SQL硬解析带来的开销。
- 结果缓存(Result Cache):存储查询最终结果集,仅当执行计划出现
- Exadata平台存在额外的存储层缓存:存储节点自带的智能闪存缓存(Smart Flash Cache)会在存储侧缓存热点数据块,即便清空数据库实例层面的缓存,存储层缓存依然会让查询性能高于真实冷启动水平。
无高权限场景下排除缓存干扰的正确测试方法
你最初计划执行的alter system flush buffer_cache;和alter system flush shared_pool;属于实例级高危操作,需要系统权限,且会清空整个实例所有业务的缓存,本身就不符合正规性能测试的规范,不建议使用。可以按照以下方案开展测试,不需要额外系统权限:
- 结果缓存校验:当前你的查询无结果缓存参与,不需要添加
/*+ NO_RESULT_CACHE */提示,这部分已经不会干扰测试结果。 - 区分场景做性能度量,不要无脑追求"完全无缓存"的极端场景:
- 热缓存场景(模拟业务运行中重复查询的真实性能):第一次执行查询做预热,不计入统计,后续连续执行3-5次查询,去掉最高最低值后取平均耗时即可,这是最贴近生产实际的性能指标。
- 冷缓存场景(模拟查询首次运行的性能):不需要刷全实例缓存,每次测试前执行两个操作即可:
- 对测试涉及的所有表执行单行更新后回滚,例如
UPDATE 测试表 SET 任意非空列=任意非空列 WHERE ROWNUM=1; ROLLBACK;,该操作仅需要表的更新权限,会将Buffer Cache中对应表的所有缓存块标记为失效,后续查询必须重新从存储读取数据,绕开数据块缓存影响。 - 针对Exadata存储层缓存,在查询中添加
/*+ STORAGE(FLASH_CACHE_BYPASS) */提示,直接跳过存储节点闪存缓存读取数据,避免存储层缓存干扰。
- 对测试涉及的所有表执行单行更新后回滚,例如
- 执行计划校验:每次测试前可以通过
EXPLAIN PLAN确认执行计划稳定,避免执行计划波动导致的性能数据偏差。
注意:不要在生产环境执行实例级刷缓存操作,该操作会导致短时间内所有业务查询都要重新读磁盘,极易引发业务性能雪崩。
内容的提问来源于stack exchange,提问作者mpdegn
相关产品推荐
相关产品推荐

