Oracle的EXPLAIN PLAN有多准确?

时间:2009-05-06 14:14:27

标签: sql oracle oracle10g sql-execution-plan

有没有什么好方法可以客观地衡量Oracle 10g中的查询性能?有一个特定的查询,我已经tuning几天了。我有一个似乎运行得更快的版本(至少基于我的初始测试),但EXPLAIN的成本大致相同。

  1. EXPLAIN成本丢失的可能性有多大?
  2. 在任何特定情况下,EXPLAIN的成本与查询的实际性能不成比例吗?
  3. 我在此查询中使用了first_rows提示。这有影响吗?

4 个答案:

答案 0 :(得分:12)

  

EXPLAIN成本丢失的可能性有多大?

非常不可能。实际上,这将是一个级别1错误:)

实际上,如果您的统计信息与运行EXPLAIN的时间相比发生了很大变化,那么实际的查询计划就会有所不同。但随着查询的失败,计划将保持不变。

注意EXPLAIN PLAN可能会显示可能发生的事情,但可能永远不会发生在实际查询中。

就像,如果您在分层查询上运行EXPLAIN PLAN

SELECT  *
FROM    table
START WITH
        id = :startid
CONNECT BY
        parent = PRIOR id

idparent的索引,你会看到额外的FULL TABLE SCAN,这很可能在现实生活中不会发生。

使用STORED OUTLINE来存储和重复使用该计划,无论如何。

  

在任何特殊情况下,EXPLAIN的成本与查询的实际性能有不同的差异吗?

是的,它经常发生在复杂的查询上。

CBO(基于成本的优化程序)使用计算的统计信息来评估查询时间并选择最佳计划。

如果你的查询中有大量的JOIN,子查询和这些类型,它的算法无法准确预测哪个计划会更快,特别是当你达到内存限制时。

以下是您询问的特定情况:例如,HASH JOIN如果哈希表不适合probe table,则需要多次传递pga_aggregate_table,但截至Oracle 10g 1}},我不记得CBO要考虑到这一点。

这就是为什么我提示每个查询我希望在最坏的情况下运行时间超过2秒。

  

我在此查询中使用了first_rows提示。这有影响吗?

此提示将使优化器使用具有较低响应时间的计划:尽管整体查询时间较长,它仍会尽快返回第一行。

实际上,它几乎总是意味着使用NESTED LOOP代替HASH JOIN

NESTED LOOP在大型数据集上的整体性能较差,但它们更快地返回第一行(因为不需要构建哈希表)。

至于original question的查询,请参阅我的回答here

答案 1 :(得分:6)

问:有没有什么好方法可以客观地衡量查询在Oracle 10g中的性能?

  • Oracle跟踪是衡量绩效的最佳方式。执行查询并让Oracle检测执行。在SQLPlus环境中,使用AUTOTRACE非常容易。

http://asktom.oracle.com/tkyte/article1/autotrace.html (文章已移动)
http://tkyte.blogspot.com/2007/04/when-explanation-doesn-sound-quite.html
http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:5671636641855

在其他环境中启用Oracle跟踪并不困难。

问:有一个特定的查询我几天都在调整。我有一个似乎运行得更快的版本(至少基于我的初始测试),但EXPLAIN的成本大致相同。

  • 该陈述的实际执行是需要衡量的。 EXPLAIN PLAN在预测优化器计划方面做得不错,但实际上并没有衡量性能。

问:> 1。 EXPLAIN成本丢失的可能性有多大?

  • 不太可能,但我看到EXPLAIN PLAN提出的计划与优化程序不同。

问:> 2。在任何特定情况下,EXPLAIN成本与查询的实际性能不成比例地不同吗?

  • 简短的回答是我没有观察到任何。但话说再说一次,EXPLAIN PLAN成本与实际观察到的性能之间并没有直接关联。 EXPLAIN PLAN可以为成本提供非常高的数字,但让实际查询在不到一秒的时间内运行。 EXPLAIN PLAN不会测量查询的实际性能,因为您需要Oracle跟踪。

问:> 3。我在这个查询中使用了first_rows提示。这有影响吗?

  • 任何提示(如/*+ FIRST_ROWS */)都可能影响优化程序选择的计划。

EXPLAIN PLAN返回的“费用”是相对的。这是性能的指标,但不是准确的衡量标准。您无法将成本编号转换为多个磁盘操作或多个CPU秒或等待事件数。

通常情况下,我们发现EXPLAIN PLAN成本显示为1的语句将“非常快”地运行,并且EXPLAIN PLAN成本大约为五位或六位的语句将花费更多时间跑。但并非总是如此。

优化器正在做的是比较许多可能的执行计划(全表扫描,使用索引,嵌套循环连接等)。优化器为每个计划分配一个编号,然后选择编号最小的计划

我见过EXPLAIN PLAN显示的优化器计划 NOT 与执行语句时使用的实际计划相匹配的情况。十年前我在Oracle8中看到了这一点,特别是当语句涉及绑定变量而不是文字时。

要获取语句执行的实际成本,请为语句启用跟踪。 最简单的方法是使用SQLPlus AUTOTRACE。

[http://asktom.oracle.com/tkyte/article1/autotrace.html][4]

在SQLPlus环境之外,您可以打开Oracle跟踪:

    alter session set timed_statistics = true;
    alter session set tracefile_identifier = here_is_my_session;
    alter session set events '10046 trace name context forever, level 12'
    --alter session set events '10053 trace name context forever, level 1'
    select /*-- your_statement_here --*/ ...
    alter session set events '10046 trace name context off'
    --alter session set events '10053 trace name context off'

这会将跟踪文件放入服务器上的user_dump_dest目录中。生成的tracefile将具有语句计划AND所有等待事件。 (分配的跟踪文件标识符包含在文件名中,可以更容易地在udump目录中找到您的文件)

    select value from v$parameter where name like 'user_dump_dest'

如果您无权访问跟踪文件,则需要从dba获取帮助才能访问。 (dba可以创建一个简单的shell脚本,开发人员可以针对.trc文件运行以运行tkprof,并更改跟踪文件和tkprof输出的权限。您还可以使用更新的trcanlzr。有关于Oracle metalink的说明两者。

答案 2 :(得分:1)

AFAIK,EXPLAIN正在使用一些数据库统计数据来计算成本,因此它肯定会与实际性能不同。

答案 3 :(得分:0)

根据我的经验,EXPLAIN是准确和有益的。如果不是它可能不是有用的工具。你最后一次分析表是什么时候?我已经看到解释计划在分析之前和之后几乎相同,但分析取得了巨大的性能提升。