【问题标题】:How accurate is Oracle's EXPLAIN PLAN?Oracle 的解释计划的准确性如何?
【发布时间】:2010-10-24 05:00:13
【问题描述】:

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

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

【问题讨论】:

    标签: sql oracle oracle10g sql-execution-plan


    【解决方案1】:

    EXPLAIN 成本遗漏的可能性有多大?

    不太可能。其实会是一个级别1bug :)

    实际上,如果您的统计数据与您运行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,我不请记住,CBO 会考虑到这一点。

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

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

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

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

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

    至于你original question的查询,看我的回答here

    【讨论】:

    • +1,xlnt,有见地的答案,像往常一样。那么,您是否在枕边睡觉时使用 Oracle RDBMS 源代码或其他什么东西? ;-)
    • @DCookie: 不,我 8 岁的时候被 Tom Kyte 咬了 :)
    • 对于更复杂的查询,优化器会检查所有可能的路径,还是会采用实用的截止选项,接受它可能会错过更好的解决方案?我自己仍然怀念旧的基于规则的优化器。你知道你在哪里使用基于规则的优化器(mutter,mumble)......
    • 有时需要根据执行查询的sql_id查看v$sql_plan,看看它实际使用的是什么计划。有时,它说在您运行解释计划时将使用的计划并不是它最终选择的计划。我现在正在处理这样的问题。我可以看到这两个计划,我可以看到差异,但我无法说服它不要使用“MERGE JOIN CARTESIAN”。
    • @vmatyi:对不起,我不能。它只是出现在那里,但据我所知,它从未出现在剧中。可能这是优化器可能在认为合适的情况下使用的某种后备策略。不幸的是,Oracle 并未详细披露优化器的内部结构。
    【解决方案2】:

    问:在 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 显示的优化器计划与执行语句时使用的实际计划匹配的情况。十年前我在 Oracle8 中看到了这一点,特别是当语句涉及绑定变量而不是文字时。

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

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

    在SQLPlus环境之外,可以开启Oracle Tracing:

    更改会话设置 timed_statistics = true; 更改会话集 tracefile_identifier = here_is_my_session; 更改会话集事件'10046 永远跟踪名称上下文,级别 12' --alter session set events '10053 永远跟踪名称上下文,级别 1' 选择 /*-- your_statement_here --*/ ... 更改会话集事件“10046 跟踪名称上下文关闭” --alter session set events '10053 跟踪名称上下文关闭'

    这会将跟踪文件放入服务器上的 user_dump_dest 目录。生成的跟踪文件将包含语句计划和所有等待事件。 (分配的跟踪文件标识符包含在文件名中,便于在 udump 目录中找到您的文件)

    从 v$parameter 中选择值,其中名称如 'user_dump_dest'

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2020-10-16
          • 1970-01-01
          • 2012-11-12
          • 2012-12-16
          • 2012-04-16
          • 1970-01-01
          • 2017-11-05
          • 2013-02-02
          • 2019-08-12
          相关资源
          最近更新 更多