Oracle的EXPLAIN PLAN有多准确?

Jas*_*ker 4 sql oracle oracle10g sql-execution-plan

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

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

Qua*_*noi 12

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

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

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

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

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

SELECT  *
FROM    table
START WITH
        id = :startid
CONNECT BY
        parent = PRIOR id
Run Code Online (Sandbox Code Playgroud)

与这两个指标idparent,你会看到一个额外的FULL TABLE SCAN大多数可能不会发生在现实生活.

STORED OUTLINE无论如何,使用's来存储和重用计划.

是否有任何特殊情况下EXPLAIN成本与查询的实际性能不成比例?

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

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

如果JOIN查询中的内容中包含大量的子查询和子查询,则其算法无法准确预测哪个计划会更快,尤其是在达到内存限制时.

下面是你问的具体情况:HASH JOIN举例来说,将需要几个越过probe table如果哈希表将不适合pga_aggregate_table,但作为Oracle 10g,我不记得这个曾经被考虑在内CBO.

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

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

此提示将使优化器使用响应时间较短的计划:尽管总查询时间较长,但它将尽快返回第一行.

实际上,它几乎总是意味着使用NESTED LOOP'而不是HASH JOIN's.

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

至于从您的查询原来的问题,请参阅我的答案在这里.


spe*_*593 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秒或等待事件数.

通常情况下,我们发现显示为1的EXPLAIN PLAN成本的语句将"非常快"地运行,并且具有大约五位或六位数的EXPLAIN PLAN成本的语句将花费更多时间来运行.但不总是.

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

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

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

[http://asktom.oracle.com/tkyte/article1/autotrace.html][4]
Run Code Online (Sandbox Code Playgroud)

在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的说明都.