嵌套内联查询比Equal Join更快

时间:2013-05-23 08:58:46

标签: sql performance oracle

假设有两个表:

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)。

1 个答案:

答案 0 :(得分:1)

您最有可能从Scalar子查询缓存中获益。我最近在博客上发表了关于Oracle 11g(或10g?)的这一强大功能的补充内容:

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

查看您的执行计划,您会在计划的顶部找到一些奇怪的元素,表明实际的子查询并未真正针对源自TRANSACTIONS表的每一行进行评估。这是因为Oracle's CBO introspects constraint metadata推导出TRANSACTIONS中的每一行,ITEMS中只有一个匹配的行,如果使用ITEM_CODE进行等联。这些知识使您的子查询受到缓存。如果TRANSACTIONS.ITEM_CODE有许多相等的值,缓存可以起到非常积极的作用。

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