[英]Oracle Rownum SQL
這兩種編碼技術之間有什么區別(優點和缺點)?
select * from (
select rownum rnun, * from table where rownum < x
) where rnum > y
select * from (
select * from table
) where rownum < x and x > y
這兩個查詢返回不同的行。
這兩個查詢都不是確定性的。 因此,任何查詢都不應該在實際系統中使用。
第一個查詢似乎至少是嘗試生成行(x 和 y 之間的行)的 window。 但是,由於沒有 ORDER BY,因此行的順序不是確定性的,並且 window 可能無法滿足您的要求。
第二個查詢返回任意 x 行數據(假設 x > y)。 否則返回 0 行(如果 y >= x)。 如果您正在嘗試構建某種窗口查詢,則不是這樣。
如果你想要一個有效的窗口查詢,你會想要類似的東西
SELECT *
FROM (SELECT a.*,
row_number() over (order by something) rnum
FROM table_name)
WHERE rnum BETWEEN x AND y
如果你想使用 ROWNUM,你需要類似的東西
SELECT *
FROM (SELECT a.*,
rownum rnum
FROM( SELECT b.*
FROM table_name
ORDER BY something) a)
WHERE rownum < y
AND rnum > x
但這往往比分析查詢方法效率低。
除了沒有“order by”條款之外……問題可能是關於 Oracle STOPKEY 功能? 在“分頁”查詢的情況下,Oracle 可以使用 STOPKEY 功能來限制子查詢中的行數,這可能會帶來一些性能提升。
看看這個查詢:
select *
from (select a.*,
row_number() over (order by sname) rnum
from t_patient_card a)
where rnum between 1 and 100
Cost Cardinality
SELECT STATEMENT, GOAL = FIRST_ROWS 313272 3571266
VIEW HOSPITAL2$ 313272 3571266
SORT ORDER BY 313272 3571266
COUNT
TABLE ACCESS FULL HOSPITAL2$ T_PATIENT_CARD 38883 3571266
Oracle 之前獲取的所有行只返回其中的 100 個
讓我們像這樣重寫查詢:
select *
from (
select rownum as rn,tt.* from
(
select t.* from t_patient_card t order by t.sname
)tt where rownum<100
)
WHERE rn >1
在這種情況下,我們在子查詢中使用 rownum<100 來通知優化器我們想要減少 100 行。
Cost Cardinality
SELECT STATEMENT, GOAL = ALL_ROWS 313272 99
VIEW HOSPITAL2$ 313272 99
COUNT STOPKEY
VIEW HOSPITAL2$ 313272 3571266
SORT ORDER BY STOPKEY 313272 3571266
TABLE ACCESS FULL HOSPITAL2$ T_PATIENT_CARD 38883 3571266
在這一步之后,您可以看到“count stopkey”和基數只有 99。在我的數據庫中,第二個查詢的執行速度比第一個查詢快一秒。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.