【问题标题】:How does Oracle calculate the cost in an explain plan?Oracle 如何计算解释计划中的成本?
【发布时间】:2012-04-16 11:05:37
【问题描述】:

谁能解释在 Oracle 解释计划中如何评估成本? 是否有任何特定的算法来确定查询的成本?

例如:全表扫描成本更高,索引扫描成本更低……Oracle如何评估full table scanindex range scan等的案例?

这个链接和我问的一样:Question about Cost in Oracle Explain Plan

但是谁能举个例子解释一下,我们可以通过执行explain plan找到代价,但是它内部是如何工作的呢?

【问题讨论】:

    标签: performance oracle oracle10g oracle11g query-tuning


    【解决方案1】:

    计算成本有很多很多特定的算法。远远超过这里可以实际讨论的内容。乔纳森·刘易斯 (Jonathan Lewis) 在他的书 Cost-Based Oracle Fundamentals 中介绍了基于成本的优化器如何决定查询的成本,这一点令人钦佩。如果您真的有兴趣,那将是最好的起点。

    假设全表扫描比索引扫描具有更高的成本是错误的。它取决于优化器对表中行数的估计以及优化器对查询将返回的行数的估计(这又取决于优化器对各种谓词的选择性的估计)、相对成本顺序读取与串行读取的比较、处理器的速度、磁盘的速度、缓冲区缓存中可用块的概率、数据库的优化器设置、会话的优化器设置、PARALLEL 属性你的表和索引,以及一大堆其他因素(这就是为什么需要一本书才能真正开始深入研究这类事情)。一般来说,如果您的查询将返回表中的大部分行,Oracle 将更喜欢全表扫描;如果您的查询将返回表中的一小部分行,则 Oracle 将更喜欢索引访问。而且“小部分”通常比人们最初估计的要小得多——例如,如果您要返回表中 20-25% 的行,那么使用全表扫描几乎总是更好。

    如果您尝试在查询计划中使用COST 列来确定该计划是“好”还是“坏”,那么您可能走错了路。 COST 仅在优化器的估计准确时才有效。但查询计划不正确的最常见原因是优化器的估计不正确(统计不正确,Oracle 对选择性的估计不正确等)。这意味着,如果您看到一个成本为 6 的查询的计划和一个成本为 600 万的查询的不同版本的计划,则完全有可能成本为 600 万的计划是效率更高,因为成本较低的计划错误地假设某个步骤将返回 1 行而不是 100 万行。

    您最好忽略COST 列并专注于CARDINALITY 列。 CARDINALITY 是优化器对计划每一步要返回的行数的估计。 CARDINALITY 是您可以直接测试和比较的东西。例如,如果您看到计划中的一个步骤涉及对表 A 进行完全扫描且没有谓词,并且您知道 A 大约有 100,000 行,那么优化器的 CARDINALITY 估计值是否太高或太低了。如果它估计基数为 100 或 10,000,000,那么优化器几乎肯定会错误地选择表扫描,或者将该数据输入到后面的步骤中,在该步骤中其成本估计将严重不正确,从而导致它选择一个糟糕的连接顺序或一个糟糕的连接方法。它可能表明表 A 上的统计数据不正确。另一方面,如果您发现每一步的基数估计都相当接近现实,那么 Oracle 很有可能为查询选择了一个相当好的计划。

    【讨论】:

    • 那么当我们要解释计划时,这里的成本单位到底是什么
    • @GauravSoni - 99% 的情况下,您应该忽略查询计划中的 COST 列。如果COST 准确,则查询计划几乎肯定是正确的。但是,如果您正在查看查询计划,则应该假设它可能不正确,在这种情况下您不能假设优化器的估计是正确的。您最好查看CARDINALITY 列,该列指示每个步骤处理的预期行数。如果这是对现实的合理近似,那么优化器的估计是合理的,并且计划应该是合理的。
    • :你能解释一下吗If that is a reasonable approximation of reality, the optimizer's estimates are reasonable and the plan ought to be reasonable
    • @GauravSoni - 扩展了我的答案。
    【解决方案2】:

    了解 CBO 算法的另一个起点是 Wolfgang Breitling 的this paper。乔纳森·刘易斯的书更详细,也更新,但这篇论文是一个很好的介绍。

    【讨论】:

      【解决方案3】:

      the 9i documentation 中,Oracle 生成了一个具有权威性的成本数学模型:

      Cost =  (#SRds * sreadtim + 
                 #MRds * mreadtim +  
                 #CPUCycles / cpuspeed ) / sreadtim
      

      地点:

      • #SRDs 为单块读取次数
      • #MRDs 是多块读取的次数
      • #CPUCycles 是 CPU 周期数 *)
      • sreadtim 是单块读取时间
      • mreadtim 是多块读取时间
      • cpuspeed 是每秒的 CPU 周期数

      因此,它可以很好地了解计算成本的因素。这就是为什么 Oracle 引入了收集系统统计信息的功能:为 CPU 速度等提供准确的值

      现在我们快进到the equivalent 11g documentation,我们发现数学已经被粗略的解释所取代:

      “由优化器的查询方法估计的操作成本。 未确定表访问操作的成本。这个的价值 列没有任何特定的计量单位;它只是 用于比较执行计划成本的加权值。价值 此列的值是 CPU_COST 和 IO_COST 列的函数。"

      我认为这反映了cost 并不是一个非常可靠的执行时间指标。 Jonathan Lewis 最近发布了一篇相关的博客文章。他展示了两个相似的查询;他们的解释计划不同,但他们有相同的成本。然而,在运行时,一个查询的执行速度比另一个查询慢得多。 Read it here.

      【讨论】:

        猜你喜欢
        • 2012-11-12
        • 2021-02-21
        • 2011-02-04
        • 1970-01-01
        • 2017-04-23
        • 2020-10-16
        • 2012-12-16
        • 1970-01-01
        • 2017-11-05
        相关资源
        最近更新 更多