1

假设有两个表:

TRANSACTION
Primary Key: REF_NO
Columns:     REF_NO, TXN_DATE, ITEM_CODE, QUANTITY

ITEM
Primary Key: ITEM_CODE
Columns:     ITEM_CODE, ITEM_DESC

查询(1):

SELECT T.REF_NO, T.TXN_DATE, T.ITEM_CODE,
    I.ITEM_DESC,
    T.QUANTITY
FROM TRANSACTION T, ITEM I
WHERE T.ITEM_CODE = I.ITEM_CODE

查询(2):

SELECT T.REF_NO, T.TXN_DATE, T.ITEM_CODE,
    (SELECT ITEM_DESC FROM ITEM WHERE ITEM_CODE = T.ITEM_CODE) AS ITEM_DESC,
    T.QUANTITY
FROM TRANSACTION T

必要时,两个表上都有索引(索引)。

以上是我正在做的事情的一个非常简化的版本,但概念是相同的。

有人告诉我,(1)由于索引而更有效,而解释计划实际上表明它是。(1)的解释计划显示了两个表的索引访问。(2) 的解释计划显示对 ITEM 的索引访问,但对 TRANSACTION 的全表访问。

但我的困境是,当我在非常大的数据集上运行它们以计算实际性能时,(2)比(1)快四倍!可能的原因是什么?为什么我应该选择(1)而不是(2)?(我们决定选择(2)而不是(1)。

4

1 回答 1

1

您很可能从标量子查询缓存中受益。我最近在博客中介绍了 Oracle 11g(或 10g?)的这个很棒的特性:

http://blog.jooq.org/2011/09/02/oracle-scalar-subquery-caching

查看您的执行计划,您会在计划的顶部发现一些奇怪的元素,这表明实际的子查询并未真正针对源自TRANSACTIONS表的每一行进行评估。这是因为Oracle 的 CBO 会自省约束元数据TRANSACTIONS以推断ITEMS,如果使用ITEM_CODE. 这些知识使您的子查询受到缓存的影响。如果 有许多相等的值TRANSACTIONS.ITEM_CODE,缓存可以产生非常积极的效果。

更多有用的信息可以在这里找到:

于 2013-05-23T09:13:30.753 回答