Oracle中實現分頁

2021-08-31 15:49:54 字數 2815 閱讀 6210

原文:

在oracle中實現分頁的方法大致分為兩種,用rownum關鍵字和用rowid關鍵字,下面來詳細介紹一下:

1、rownum(測試30w,240w左右資料時,第一種效果都比第二種好)

其**為:

select *

from (select row_.*, rownum rownum_

from (select *

from table1

where table1_id = xx

order by gmt_create desc) row_

where rownum <= 20)

where rownum_ >= 10;

這應該是我們大部分程式裡所用到的版本,因為這個版本很容易實現復用,中間row_部分,就是我們平常寫到的sql語句,然後再將起始條數和終止條數作為專門的分頁sql語句傳入即可查詢出我們想要的結果。

從效率上看,上面的sql語句在大多數情況擁有較高的效率,主要體現在where rownum <= 20這句上,這樣就控制了查詢過程中的最大記錄數,而在查詢的最外層控制最小值。但最大值意味著如果查到了很大的範圍(如百萬級別的資料),查詢就會從很大範圍內往裡減少,效率就會很低,因此,當面對大資料量時或者優化查詢效率時,如果你用了rownum,可以換第二種方法。

1由以上的方法,又可以引申出3種方式:

a、結合between and 

**如下:

select *

from (select a.*, rownum rn

from (select *

from table1

where table1_id = xx

order by gmt_create desc) a)

where rn between 10 and 20;

這個就是換湯不換藥了,而且查詢效率更低,因為:

oracle可以將外層的查詢條件推到內層查詢中,以提高內層查詢的執行效率,但不能跨越多層。

1由於查詢條件between 10 and 20是存在於查詢的第三層,而oracle無法將第三層的查詢條件推到最內層(即使推到最內層也沒有意義,因為最內層查詢不知道rn代表什麼)。因此,這個查詢語句,oracle最內層返回給中間層的是所有滿足條件的資料,而中間層返回給最外層的也是所有資料。資料的過濾在最外層完成,顯然這個效率要比原始的查詢低得多。

b、結合minus

select *

from table1

where rownum <= 20

minus

select * from table1 where rownum <= 10;

查詢了兩次,效率上更差了一些。

c、row_number() over( order by order_date desc) 

這個和rownum關鍵字類似,生成的順序和rownum的語句一樣,效率也一樣(對於同樣有order by 的rownum語句來說),所以在這種情況下兩種用法是一樣的。 

而對於分組後查詢做分頁的話,則是rownum無法實現的,這時只有row_number可以實現,row_number() over(partition by 分組字段 order by 排序字段)就能實現分組後編號,其**為:

select *

from (select a.*,

row_number() over(partition by trunc(order_date) order by order_date desc) rn

from table1 a)

where rn <= 10;

2、rowid

rowid仍舊需求rownum,但方式不同,因此我將其歸為另一大類,其**為:

select *

from (select rid

from (select r.rid, rownum linenum

from (select rowid rid

from table1

where table1_id = xx

order by order_date desc) r

where rownum <= 20)

where linenum >= 10) t1,

table1 t2

where t1.rid = t2.rowid;

從語句上看,共有4層select巢狀查詢,最內層為可替換的不分頁原始sql語句,但是他查詢的字段只有rowid,而沒有任何待查詢的實際表字段,具體查詢實際字段值是在最外層實現的; 

這種方式的原理大致為:

首先通過rownum查詢到分頁之後的10條實際返回記錄的rowid,最後通過rowid將最終返回字段值查詢出來並返回;

1和前面rownum實現方式相比,該sql的實現方式更加繁瑣,通用性也不是非常好,因為要將原始的查詢語句分成兩部分(查詢欄位在最外層,表及其查詢條件在最內層),想要復用就很困難了; 

但這種實現在特定場景下還是有優勢的:比如我們經常要翻頁到很後面,比如10000條記錄中我們經常需要查9000-9100及其以後的資料;此時該方案效率可能要比前面的高; 

因為前面的方案中是通過rownum <= 9100來控制的,這樣就需要查詢出9100條資料,然後取最後9000-9100之間的資料,而這個方案直接通過rowid取需要的那100條資料; 

從不斷向後翻頁這個角度來看,第一種實現方案的成本會越來越高,基本上是線性增長,而第三種方案的成本則不會像前者那樣快速,他的增長只體現在通過查詢條件讀取rowid的部分;

Oracle分頁實現

10級學員 張帥鵬課堂總結 簡單分析下如何實現 考慮mysql中的實現分頁,select from 表名 limit 開始記錄數,顯示多少條 就可以實現我們的分頁效果。但是在oracle中沒有limit關鍵字,但是有 rownum欄位 rownum是乙個偽列,是oracle系統自動為查詢返回結果的每...

Oracle分頁實現

1 在oracle資料庫中,rownum是oracle資料庫為查詢結果加入的乙個偽列。起始值為1。經常使用來處理查詢結果的分頁。2 因為rownum的特殊性,使用時候一般是分三層 第一層 先進行查詢及order by排序。第二層 查詢相應的列及rownum 第三層 在where 加入rouwnum條...

Oracle 分頁實現

分頁實現 實行兩行一頁 1 先查詢按編號排序的所有使用者資訊 select t.from t user t order byuser id 2 查詢資料的前四行,select a.rownum q from select t.from t user t order byuser id a where...