java oracle数据库高效分页查询_oracle高效分页查询总结
探索查詢語句:
--分頁參數(shù):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
-- 一次篩選(數(shù)據(jù)量大的時候,第一次查詢的數(shù)據(jù)量過大,明顯比上面慢,不推薦)
--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
-- 一次篩選(數(shù)據(jù)量大的時候,第一次查詢的數(shù)據(jù)量過大,明顯比上面慢,不推薦)
--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; --這里用>查不到數(shù)據(jù) =也查不到數(shù)據(jù) <= 或者 < 可以查到數(shù)據(jù)
----where ROWNUM BETWEEN 20*(2-1)+1 AND 20*2; --查不到數(shù)據(jù)
----where ROWNUM <=20*2 and ROWNUM > 20*(2-1); --查不到數(shù)據(jù)
----這是因為查詢時,第一條生成的rownum為1,1>20不成立,1=20也不成立,所以這條數(shù)據(jù)就作廢了,依次類推,這樣就查不到任何一條數(shù)據(jù)
--) t
--where t.rowno <=20*2 and t.rowno > 20*(2-1); --可以查到數(shù)據(jù)耗時:3.924s
---- where t.rowno BETWEEN 20*(2-1)+1 AND 20*2; --可以查到數(shù)據(jù)耗時:3.919s
--采用row_number() over 分頁函數(shù)
--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總是從1開始的,第一條不滿足去掉的話,第二條的rownum 又成了1。依此類推,所以永遠沒有滿足條件的記錄。
可以這樣理解:rownum是一個序列,是Oracle數(shù)據(jù)庫從數(shù)據(jù)文件或緩沖區(qū)中讀取數(shù)據(jù)的順序。
它取得第一條記錄則rownum值為1,第二條為2。依次類推。
當使用“>、>=、=、between...and”這些條件時,從緩沖區(qū)或數(shù)據(jù)文件中得到的第一條記錄的rownum為1,不符合sql語句的條件,會被刪除,接著取下條。
下條的rownum還會是1,又被刪除,依次類推,便沒有了數(shù)據(jù)。
所以上限條件必須放在子查詢,而下限條件必須放在外層查詢。
2、between ?and 和 >= and <=
這兩者查詢效率上來說沒有區(qū)別,between and 最終也是轉(zhuǎn)為>= and <=
所以select * from (select * from a where a.time >= to_date('19920324','yyyymmdd')) b where b.time <=?to_date('20170324','yyyymmdd')
這樣的嵌套是沒有必要的,可以直接用between 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;
SELECT *
FROM (SELECT ROWNUM AS rowno, t.*
FROM BDC_XM t
where ROWNUM <= 100) a
WHERE a.rowno > 80;
有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;
另外我們也可以使用row_number() over函數(shù):
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 size*(page-1)+1 AND page*size;
但是相比前面的并沒有什么優(yōu)勢。
總結(jié)
以上是生活随笔為你收集整理的java oracle数据库高效分页查询_oracle高效分页查询总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 半包装修多少钱啊?
- 下一篇: 位运算符Java与详解_java位运算符