查询第一次执行缓慢,但第二次/第三次执行快速

时间:2020-03-04 13:58:09

标签: sql oracle query-performance

我们在Oracle查询中看到一个非常奇怪的情况。下面的查询,

SELECT e.C1, MAX (e.Some) 
FROM MyTable e
WHERE e.Code = :Code
GROUP BY E.C1
ORDER BY MAX (e.Some)

请注意,该表包含约500万条记录,而Code是主键。

第一次尝试时,它将在60/70秒内返回该值,但在此之后,它将在500毫秒内返回结果。

Oracle中是否有任何参数嗅探,或者我们可以在Oracle中具有OPTION(RECOMPILE)?

2 个答案:

答案 0 :(得分:1)

Oracle查询在第二次或第三次执行时可能会加速的原因有几个:

  1. 缓冲区缓存-Oracle会将常用的​​表和索引块放入内存中。最简单的检查方法是启用set autotrace on后,在SQL * Plus中多次运行查询。如果“物理读取”的值在第一次运行后消失,则缓存导致了差异。但是缓存也可以在存储或操作系统级别进行。
  2. 缓慢的解析/执行构建-在极少数情况下,Oracle可能需要很长时间才能构建初始执行计划。如果使用动态采样,则尤其如此,Oracle将读取表的一部分以弥补优化器统计信息的错误。查找此问题的一种方法是查找与您的查询同时运行的其他系统查询。造成这种情况的另一个常见原因是系统性能不佳或固定对象统计信息不佳,这意味着Oracle可能很难构建查询来检查特权等内容。
  3. 基数反馈(11g)/统计信息反馈(12c +)-通过比较预期基数和实际基数,优化器可以从错误中学习。 GV $ SQL中相同的SQL_ID是否具有不同的PLAN_HASH_VALUE?如果是这样,执行计划会随着时间而改变。
  4. 结果缓存-Oracle服务器和客户端可以存储查询结果。这种缓存实际上比人们想象的要少得多,因为在实践中,缓冲区缓存更为有用-为什么当您可以存储可服务多个查询的数据块时,为什么将单个特定结果存储在内存中?

答案 1 :(得分:0)

它可能没有使用主键的索引。尝试说明计划检查。尝试使用规则库来强制使用索引:

select /*+ RULE */ from ...

另外,请DBA运行表分析以更新统计信息。