谁能解释在 Oracle 解释计划中如何评估成本?是否有任何特定的算法来确定查询的成本?
例如:全表扫描的成本较高,索引扫描的成本较低……Oracle 如何评估 、 等的 full table scan
情况index range scan
?
这个链接和我问的一样:关于 Oracle 解释计划中的成本的问题
但是谁能用一个例子来解释一下,我们可以通过执行来找到成本explain plan
,但是它在内部是如何工作的呢?
谁能解释在 Oracle 解释计划中如何评估成本?是否有任何特定的算法来确定查询的成本?
例如:全表扫描的成本较高,索引扫描的成本较低……Oracle 如何评估 、 等的 full table scan
情况index range scan
?
这个链接和我问的一样:关于 Oracle 解释计划中的成本的问题
但是谁能用一个例子来解释一下,我们可以通过执行来找到成本explain plan
,但是它在内部是如何工作的呢?
有很多很多特定的算法来计算成本。远远超过这里可以实际讨论的内容。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 很有可能为查询选择了一个相当好的计划。
另一个开始理解 CBO 算法的地方是Wolfgang Breitling 的这篇论文。乔纳森·刘易斯的书更详细、更近,但这篇论文是一个很好的介绍。
在9i 文档中, Oracle 生成了一个具有权威性的成本数学模型:
Cost = (#SRds * sreadtim + #MRds * mreadtim + #CPUCycles / cpuspeed ) / sreadtim
在哪里:
- #SRDs 是单块读取的次数
- #MRDs 是多块读取的数量
- #CPUCycles 是 CPU 周期数 *)
- sreadtim 是单块读取时间
- mreadtim 是多块读取时间
- cpuspeed 是每秒的 CPU 周期数
因此,它很好地了解了计算成本的因素。这就是 Oracle 引入收集系统统计信息的功能的原因:为 CPU 速度等提供准确的值
现在我们快进到等效的 11g 文档,我们发现数学已被粗略的解释所取代:
“优化器查询方法估计的操作成本。表访问操作的成本不是确定的。此列的值没有任何特定的度量单位;它只是一个加权值,用于比较执行计划的成本。此列的值是 CPU_COST 和 IO_COST 列的函数。”
我认为这反映了这样一个事实,cost
即不是一个非常可靠的执行时间指标。Jonathan Lewis 最近发布了一篇相关的博客文章。他展示了两个相似的查询;他们的解释计划不同,但成本相同。然而,在运行时,一个查询的执行速度比另一个查询慢得多。 在这里阅读。