1. 程式人生 > >Oracle高效分頁查詢(轉)

Oracle高效分頁查詢(轉)

-分頁引數:size = 20 page = 2
--沒有order by的查詢
-- 巢狀子查詢,兩次篩選(推薦使用)
--SELECT *
-- FROM (SELECT ROWNUM AS rowno, t.*
-- FROM DONORINFO t
-- WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
-- AND TO_DATE ('20060731', 'yyyymmdd')
-- AND ROWNUM <= 20*2) table_alias
-- WHERE table_alias.rowno > 20*(2-1);        --耗時0.05s
-- 一次篩選(資料量大的時候,第一次查詢的資料量過大,明顯比上面慢,不推薦) --select * from( --SELECT ROWNUM AS rowno, t.* --FROM DONORINFO t --WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd') AND TO_DATE ('20060731', 'yyyymmdd') --) r --where r.rowno BETWEEN 20*(2-1)+1 and 20*2; --耗時0.46s --有order by的查詢 --巢狀子查詢,兩次篩選(推薦使用)
--SELECT * --FROM (SELECT ROWNUM AS rowno,r.* -- FROM( -- SELECT * FROM DONORINFO t -- WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd') -- AND TO_DATE ('20060731', 'yyyymmdd') -- ORDER BY t.BIRTHDAY desc -- ) r -- where ROWNUM <= 20*2 -- ) table_alias -- WHERE table_alias.rowno > 20*(2-1); --耗時0.744s
-- 一次篩選(資料量大的時候,第一次查詢的資料量過大,明顯比上面慢,不推薦) --select * from ( --SELECT ROWNUM AS rowno,r.* --FROM( --SELECT * FROM DONORINFO t --WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd') --AND TO_DATE ('20060731', 'yyyymmdd') --ORDER BY t.BIRTHDAY desc --) r ----where ROWNUM <= 20; --這裡用>查不到資料 =也查不到資料 <= 或者 < 可以查到資料 ----where ROWNUM BETWEEN 20*(2-1)+1 AND 20*2; --查不到資料 ----where ROWNUM <=20*2 and ROWNUM > 20*(2-1); --查不到資料 ----這是因為查詢時,第一條生成的rownum為1,1>20不成立,1=20也不成立,所以這條資料就作廢了,依次類推,這樣就查不到任何一條資料 --) t --where t.rowno <=20*2 and t.rowno > 20*(2-1); --可以查到資料耗時:3.924s ---- where t.rowno BETWEEN 20*(2-1)+1 AND 20*2; --可以查到資料耗時:3.919s --採用row_number() over 分頁函式 --select * --from(select d.*,row_number() over(order by d.BIRTHDAY) as rownumber -- from DONORINFO d -- WHERE d.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd') -- AND TO_DATE ('20060731', 'yyyymmdd') -- ) p --where p.rownumber BETWEEN 20*(2-1)+1 AND 20*2; --耗時0.812s select * from ( select * from(select d.*,row_number() over(order by d.BIRTHDAY) as rownumber from DONORINFO d WHERE d.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd') AND TO_DATE ('20060731', 'yyyymmdd') ) p where p.rownumber <20*2 ) where rownumber > 20*(2-1); -- 耗時0.813s

從以上探索,我們得知:

(1)ROWNUM

rownum是一個序列,是Oracle資料庫從資料檔案或緩衝區中讀取資料的順序。它取得第一條記錄則rownum值為1,第二條為2,依次類推。

當使用條件查詢時,從緩衝區或資料檔案中得到的第一條記錄的rownum為1,不符合sql語句的條件,會被刪除,下條的rownum還是1,所以上限條件必須放在子查詢,而下限條件必須放在外層查詢。

(2)between and 和>=and <=

這兩者查詢效率上來說沒有區別,between and 最終也是轉為>= and <=

(3)Oracle通用分頁格式 

沒有order by

SELECT *
FROM (SELECT ROWNUM AS rowno, t.*
          FROM DONORINFO t
          WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
          AND TO_DATE ('20060731', 'yyyymmdd')
          AND ROWNUM <= page*size) table_alias
WHERE table_alias.rowno > (page-1)*size;

有order by

SELECT *
FROM (SELECT ROWNUM AS rowno,r.*
           FROM(SELECT * FROM DONORINFO t
                    WHERE t.BIRTHDAY BETWEEN TO_DATE ('19800101', 'yyyymmdd')
                    AND TO_DATE ('20060731', 'yyyymmdd')
                    ORDER BY t.BIRTHDAY desc
                   ) r
           where ROWNUM <= page*size 
          ) table_alias
WHERE table_alias.rowno > (page-1)*size;

  

 

轉地址:https://blog.csdn.net/CHS007chs/article/details/80115506