簡體   English   中英

Oracle Rownum SQL

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM