當資料量太大,例如咱們資料庫的乙個表裡,符合查詢條件的有幾十萬條資料,如果你一次性查詢出來的話,不僅查詢速度很慢,響應時間太長影響使用者體驗,而且使用者也看不了這麼多資料。
可能有人會說可以在後台進行分頁類封裝處理(邏輯分頁
),那你首先要把查詢到的幾十萬條資料存在記憶體裡,這樣看來,還是推薦資料庫分頁查詢(物理分頁
)吧
首先,兩種格式都有三層查詢。
cbo優化模式下,oracle可以將外層的查詢條件,推到內層(只能向內推一層)查詢中,以提高內層查詢的執行效率。
對於格式1的第二層查詢條件,where rownum <=end (page*pagesize)
就可以被推入內層查詢中,這樣的話,oracle查詢的結果一旦超過了rownum的限制條件,就終止查詢,將結果返回了。
-- 格式1(推薦)
select
*from
(select
temp.*
, rownum rn
from
(select
*from 表名)
temp
where rownum <=
end(page*pagesize)
)where rn >=
start
(page-1)
*pagesize
但是格式2的rownum限制條件,是放在了第三層的查詢語句中,oracle無法把第三層的內推到第一層(即使推到最內層也沒有意義,因為最內層不知道rn是啥,rn是定義在第二層的)
-- 格式2
select
*from
(select
temp.*
, rownum rn
from
(select
*from table_name)
temp
)where rn between
start
(page-1)
*pagesize and
end(page*pagesize)
因此,對於格式2查詢語句,最內層返回給第二層所有符合條件的資料,第二層返回給第三層所有符合條件的資料,過濾資料發生在第三層;而格式1,在第一層的時候就將資料過濾好了,再將量減少了的資料向外返回,是不是效率自然就高了起來。
注意:上述兩種格式,針對最內層是複雜多表聯合的查詢,也同樣適用。
union
、union all
、minus
、intersect
、group by
、distinct
、unique
以及聚集函式如max
、min
和分析函式
等操作是針對,全部符合條件的資料的結果集,的乙個操作,所以如果最內層的子查詢中包含了這些操作中的乙個以上,那麼rownum
會不起作用,分頁查詢的效能等於沒實現。
oracle10g的新功能group by stopkey
,使得oracle10g解決了group by操作分頁效率低的問題。在10g以前,oracle的group by操作必須完全執行完,才能將結果返回給使用者。但是oracle10g增加了group by stopkey
執行路徑,使得使用者在執行group by
操作時,可以根據stopkey
隨時中止正在執行的操作。這使得標準分頁函式對於group by
操作重新發揮了作用。
操作執行原理
執行查詢操作;
將第一行的rownum置為1;
將得到的行的rownum與條件相比較,如果不匹配,則拋棄行,如果匹配,則返回行;
oracle獲取下一行,然後將rownum增1;
返回第3步;
直到超過rownum的限制條件;
rownum 使用注意事項
rownum不能以任何基表的名稱作為字首。
子查詢中的rownum必須要有別名,否則還是不會查出記錄來,這是因為rownum不是某個表的列,如果不起別名的話,無法知道rownum是子查詢的列還是主查詢的列。
查詢rownum在某區間的資料,rownum對小於某值的查詢條件為true,對於大於某值的查詢條件直接認為是false的,但是可以間接的讓它轉為認為是true的。那就必須使用子查詢。
對於表連線來說,在寫分頁查詢的時候,可以考慮增加first_rows
提示,它會導致cbo選擇nested loop
,有助於更快的將查詢結果返回。
其實,不光是表連線,對於所有的分頁查詢都可以加上first_rows
提示。
-- 格式3
select first_rows *
from
(select
temp.*
, rownum rn
from
(select
*from table_name)
temp
)where rn between
start
(page-1)
*pagesize and
end(page*pagesize)
不過需要注意的時,分頁查詢的目標是盡快的返回前n條記錄,因此,無論是rownum
還是first_rows
機制都是提高前幾頁的查詢速度,對於分頁查詢的最後幾頁,採用hash join
的方式,執行效率幾乎沒有任何改變,而採用nested loop
方式,則效率嚴重下降,而且遠遠低於hash join
的方式。
當用來排序的列存在值相等的行,可能會造成資料重複出現,因為oracle的排序演算法不具有穩定性,即鍵值相等的資料a和b,在排序之前a在b的前面,在排序之後a不一定在b的前面了(排序演算法的穩定性評判標準)。
解決辦法:
排序的時候,除了需要字段,跟乙個有索引的字段,例如主鍵;
跟rowid也可以,這種方法最簡單,且對效能的影響最小。
參考鏈結1
參考鏈結2
Oracle實現分頁查詢
今天整理下oracle分頁查詢,希望能夠幫到其他小夥伴。oracle分分頁查詢格式 select from select a.rownum rn from select from table name a where rownum 40 where rn 21其中最內層的查詢select from ...
oracle分頁查詢的實現
分頁查詢格式 select from select a.rownum rn from select from table name a where rownum 40 where rn 21其中最內層的查詢select from table name表示不進行翻頁的原始查詢語句。rownum 40和...
解析Oracle實現分頁查詢語句
第一種分頁 select from select rownum rn,e.from emp e where rownum 10 where rn 1 rownum 10和rn 0控制分頁查詢的每頁的範圍。上面給出的這個分頁查詢語句,在大多數情況擁有較高的效率。分頁的目的就是控制輸出結果集大小,將結果...