Oracle高效分頁查詢(轉)
阿新 • • 發佈:2019-01-03
-分頁引數: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