Oracle 實現分頁查詢

2021-09-03 02:43:30 字數 3135 閱讀 7696

當資料量太大,例如咱們資料庫的乙個表裡,符合查詢條件的有幾十萬條資料,如果你一次性查詢出來的話,不僅查詢速度很慢,響應時間太長影響使用者體驗,而且使用者也看不了這麼多資料。

可能有人會說可以在後台進行分頁類封裝處理(邏輯分頁),那你首先要把查詢到的幾十萬條資料存在記憶體裡,這樣看來,還是推薦資料庫分頁查詢(物理分頁)吧

首先,兩種格式都有三層查詢。

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,在第一層的時候就將資料過濾好了,再將量減少了的資料向外返回,是不是效率自然就高了起來。

注意:上述兩種格式,針對最內層是複雜多表聯合的查詢,也同樣適用。

unionunion allminusintersectgroup bydistinctunique以及聚集函式如maxmin分析函式等操作是針對,全部符合條件的資料的結果集,的乙個操作,所以如果最內層的子查詢中包含了這些操作中的乙個以上,那麼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控制分頁查詢的每頁的範圍。上面給出的這個分頁查詢語句,在大多數情況擁有較高的效率。分頁的目的就是控制輸出結果集大小,將結果...