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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM