1. 程式人生 > >Oracle資料庫分頁查詢語句與優化

Oracle資料庫分頁查詢語句與優化

回顧了之前做的專案,看到查詢分頁功能,發現有可以優化的地方。
總的來說優化過程有三個階段:
一、

select * from (select A.*, rownum rn from (select * from table_name)A)  where rn between 21 and 40;

這條分頁查詢語句最為簡單,也很好理解,老套路三層巢狀迴圈,最內層先查出所有記錄,次層查出所有記錄以及記錄偽列,最外層根據偽列查詢所有下限到上限的記錄。這條查詢語句雖然簡單,但是查詢效率很低,每一次查詢都要把所有記錄查一次,查詢效率對於資料量很大的情況來說很難接受。

二、

select
* from (select A.*, rownum rn from (select * from table_name)A where rowmun <= 40where rn > 21;

這個查詢也很容易理解,第一層同樣先查詢所有記錄,第二次根據偽列rownum來過濾掉上限以外的記錄,最外層根據偽列下限擷取記錄。大多數情況下,這個查詢要比第一個查詢語句快得多,因為Oracle在基於代價優化的機制下,會把第二次的查詢條件提到內層,這樣的話,每次查詢只是查詢一到偽列上限條記錄,比第一條查詢語句的每次查詢所有記錄要好得多。那麼為什麼說是“大多數情況下”呢,因為隨著頁數往後翻,偽列得上限也就越接近於所有記錄,也就是說,即使在優化的情況下,第二條查詢語句的查詢記錄數會越來越接近第一條查詢語句,等到翻到最後一頁的時候,兩條查詢語句效率就相同了。

三、

select * from table_name t (select rd from (select rowid rd, rownum rn from table_name where rownum <= 40)  where rn > 20)t1 where t.rowid = t1.rd;

這條語句是在第二條語句的情況下做了優化,基本原理大同小異,用偽列rowid 來做表自身的關聯,內層查詢只查詢了rownum<=40的兩個欄位rowid 和rownum,避免了使用 * ,次層查詢查 rownum>20的 rowid欄位,這層也避免了 * ,最外層用查詢出來的rowid 和原表的rowid 做自身關聯,查出所需要的欄位。