2010-04-29 40 views
6

我正在處理一個oracle數據庫,試圖調整一些查詢,而且我很難理解爲什麼以特定方式處理特定的子句對查詢性能有如此嚴重的影響。下面是該查詢的高性能版本我做爲什麼這些看似相似的查詢具有如此不同的運行時間?

select * from 
(
    select a.*, rownum rn from 
    ( 
     select * 
     from table_foo 
    ) a where rownum <= 3 
) where rn >= 2 

同樣的查詢與此

) a where rownum >=2 rownum <= 3 
) 

進行更換可怕的最後兩行。幾個數量級更差

) a where rownum between 2 and 3 
) 

也表現可怕。我不明白第一個查詢中的魔法,以及如何將它應用於進一步的類似查詢。

+3

您可以運行查詢分析('EXPLAIN PLAIN',http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/ex_plan.htm)以查看DBMS如何運行查詢。 – outis 2010-04-29 20:01:28

+0

作爲一個方面說明,爲什麼'select *'當你可以簡單地'select * from(從table_foo a中選擇a。*,rownum rown其中rownum <= 3)其中rn> = 2'? – 2010-04-30 10:05:22

回答

4

我的理解是發生rownum分配之後(或'as')行被選中,所以任何'ROWNUM> = n'查詢的n大於1將會引起麻煩。向我解釋的是,第一行是關注的;它是rownum 1,所以它不符合標準並被扔掉。下一行是看着;它仍然是rownum 1,因爲結果集是空的,並且不符合標準並被丟棄。這個過程一直持續到所有的行都被讀取和拒絕。

長時間運行的查詢是否實際產生任何數據?還是你總是在它完成之前殺死它?

+0

答案是肯定的 - 如果他的ROWNUM> = 2(即當ROWNUM = 1時任何謂詞的計算結果爲FALSE),查詢將簡單地遍歷整個數據集並不返回任何內容。 – 2010-04-30 04:03:22

+0

我實際上已經嘗試過這一點,是的,查詢會直接運行,直到所有的行都耗盡並且什麼都不返回。因此,本質上,有問題的查詢不完全相同。 – 2010-04-30 10:03:20

1

ROWNUM是查詢中可用的僞列(不是真正的列)。 ROWNUM將被分配數字1,2,3,4,... N,其中N是ROWNUM中使用的行數。在第一種情況下,您正在切斷蝙蝠的行數,而在第二種情況下,您必須查找所有切斷大於2的東西。

相關問題