2011-07-25 61 views
0

TableX的Oracle SQL IN語句:是否按順序執行?

number doc 
number item 
number parentItem 

隨着數據:

1, 1000, 0 
1, 1010, 1000 
1, 1020, 1000 
1, 2000, 0 
1, 2010, 2000 


TableY

number doc 
number item 
varchar2(16) SomeData 

隨着數據:

1, 1000, "1000 Data" 
1, 2000, "2000 Data" 


我用下面的SQL查詢來從TableY

select x.doc, x.item, y.SomeData from TableX x 
join TableY y 
on y.doc = x.doc and y.item IN (x.item, x.ParentItem) 

獲得 「SomeData」 應該結果是在:

1, 1000, "1000 Data" 
1, 1010, "1000 Data" 
1, 1020, "1000 Data" 
1, 2000, "2000 Data" 
1, 2010, "2000 Data" 

我的問題是:是對IN-聲明評估順序,或者這取決於Oracle採取的路徑?


編輯 我的意思是,當有在TableY一個項目從TableX的(如1000),一個條目將這個值可以首先在使用JOIN或將ParentItem首先使用? 或者只有在項目上的JOIN失敗時纔會對ParentItem執行JOIN操作?

+1

我不確定在這種情況下,「順序評估」到底是什麼意思。你問IN語句是否保證在連接條件之後被應用?您是否在IN子句中詢問兩個值是否存在短路評估?或者你在問別的嗎? –

+1

如果您關心的是結果集的排序,您可以保證使用ORDER BY進行排序。否則,評估順序應該不重要。 –

+0

見[編輯]註釋 –

回答

4

通常,使用數據庫時,除非指定一個數據庫,否則沒有順序。我認爲IN總是檢查整個列表,而不是在發現匹配時發生短路,但是不能保證列表將被處理的順序(如果它檢查整個列表則不重要)。


根據修改後的問題:

Oracle無法創建基於行包含的內容執行計劃,使優化器將制定一個計劃,以最有效的方式查找兩列可能。這個計劃將取決於你的表格大小和你創建的索引。

一次處理表幾乎總是更快,所以優化器可能會選擇一個路徑,在該路徑中,它可以輕鬆地檢查兩個列,而不是一次一個檢查列。這意味着,除非它有更好的途徑,否則可能會進行全表掃描。有一點實驗表明,即使索引覆蓋了兩列,優化器也會選擇全表掃描。

有趣的是,這似乎是少數情況下可能更好地將兩列分別索引的情況之一。如果兩列上都有單獨的索引,看起來優化器將掃描兩個索引,然後使用bitmap or從每個結果集中獲取唯一的rowid集。

這裏需要說明的是,我的研究是在大型桌子上使用高度人造的場景完成的。您應該以最簡單,最容易閱讀(和維護)的方式構建查詢,然後測試它的實際性能並查看它的解釋計劃。只有在確定存在性能問題(或者可能存在性能問題)時,才應該擔心找到另一種更有效(但可能不那麼明瞭)的方式來編寫查詢。一般來說,如果你有一個經過深思熟慮的sargable查詢,優化器將在挑選最有效的路徑方面做得很好。

0

評估順序無關緊要。 IN聲明僅僅是說y.item = x.item OR y.item = x.ParentItem OR ...的簡短方法。