要在Oracle中查詢top-n行,通常使用ROWNUM。 所以下面的查詢似乎確定(獲取最新的5個金):Oracle ROWNUM性能
select a.paydate, a.amount
from (
select t.paydate, t.amount
from payments t
where t.some_id = id
order by t.paydate desc
) a
where rownum <= 5;
但對於非常大的表,它是低效的 - 對我來說,運行約10分鐘。 所以,我想其他的查詢,我結束了這一次它運行了不到一秒鐘:
select *
from (
select a.*, rownum
from (select t.paydate, t.amount
from payments t
where t.some_id = id
order by t.paydate desc) a
)
where rownum <= 5;
要了解發生了什麼事,我看着每個查詢執行計劃。對於第一個查詢:
SELECT STATEMENT, GOAL = ALL_ROWS 7 5 175
COUNT STOPKEY
VIEW 7 5 175
TABLE ACCESS BY INDEX ROWID 7 316576866 6331537320
INDEX FULL SCAN DESCENDING 4 6
而對於第二:
SELECT STATEMENT, GOAL = ALL_ROWS 86 5 175
COUNT STOPKEY
VIEW 86 81 2835
COUNT
VIEW 86 81 1782
SORT ORDER BY 86 81 1620
TABLE ACCESS BY INDEX ROWID 85 81 1620
INDEX RANGE SCAN 4 81
顯然,索引全掃描DESCENDING,使低效的大表第一個查詢。但我無法通過查看它們來區分兩個查詢的邏輯。 任何人都可以解釋兩種人類語言查詢之間的邏輯差異嗎?
在此先感謝!
id是綁定變量,否(應該是:id?)如果是這樣,使用了什麼值(相同?) – tbone 2012-02-03 12:30:05
我不認爲你在第二個版本中用於過濾器的'rownum'是保證和第一個一樣;認爲你需要別名你的第二個查詢並引用它,或者在查詢中添加'order by rownum'來反對'a'?我懷疑這會影響速度。 – 2012-02-03 13:12:22