Oracle分頁查詢效率對比

oracle中無limit占贫,實現(xiàn)此功能需要使用rownum型奥,如limit10:

select * from tableName where rownum <= 10;

返回11到20行:

select * from (select rownum rn,t.* from tableName t) where rn<=20 and rn >=11; 

1.無ORDER BY排序的寫法厢汹。(效率最高)

(經(jīng)過測試烫葬,此方法成本最低,只嵌套一層,速度最快!即使查詢的數(shù)據(jù)量再大月匣,也幾乎不受影響锄开。)

SELECT *

  FROM (SELECT ROWNUM AS rowno, t.*

          FROM emp t

         WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

                             AND TO_DATE ('20060731', 'yyyymmdd')

           AND ROWNUM <= 20) table_alias

 WHERE table_alias.rowno >= 10;

2.有ORDER BY排序的寫法。(效率較高)

(經(jīng)過測試称诗,此方法隨著查詢范圍的擴大萍悴,速度也會越來越慢!)

SELECT *

  FROM (SELECT tt.*, ROWNUM AS rowno

          FROM (  SELECT t.*

                    FROM emp t

                   WHERE hire_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

                                       AND TO_DATE ('20060731', 'yyyymmdd')

                ORDER BY create_time DESC, emp_no) tt

         WHERE ROWNUM <= 20) table_alias

 WHERE table_alias.rowno >= 10;

3.無ORDER BY排序的寫法寓免。(建議使用方法1代替)

(此方法隨著查詢數(shù)據(jù)量的擴張癣诱,速度會越來越慢!)

SELECT *

  FROM (SELECT ROWNUM AS rowno, t.*

          FROM k_task t

         WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

                               AND TO_DATE ('20060731', 'yyyymmdd')) table_alias

 WHERE table_alias.rowno <= 20 AND table_alias.rowno >= 10;

--TABLE_ALIAS.ROWNO  between 10 and 100;

4.有ORDER BY排序的寫法.(建議使用方法2代替)

(此方法隨著查詢范圍的擴大袜香,速度會越來越慢撕予!)

SELECT *

  FROM (SELECT tt.*, ROWNUM AS rowno

          FROM (  SELECT *

                    FROM k_task t

                   WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

                                         AND TO_DATE ('20060531', 'yyyymmdd')

                ORDER BY fact_up_time, flight_no) tt) table_alias

 WHERE table_alias.rowno BETWEEN 10 AND 20;

5.另類語法。(有ORDER BY寫法)

(語法風格與傳統(tǒng)的SQL語法不同蜈首,不方便閱讀與理解实抡,為規(guī)范與統(tǒng)一標準欠母,不推薦使用。)

WITH partdata AS

     (

        SELECT ROWNUM AS rowno, tt.*

          FROM (  SELECT *

                    FROM k_task t

                   WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

                                         AND TO_DATE ('20060531', 'yyyymmdd')

                ORDER BY fact_up_time, flight_no) tt

         WHERE ROWNUM <= 20)

SELECT *

  FROM partdata

 WHERE rowno >= 10;

6另類語法 吆寨。(無ORDER BY寫法)

WITH partdata AS

     (

        SELECT ROWNUM AS rowno, t.*

          FROM k_task t

         WHERE flight_date BETWEEN TO_DATE ('20060501', 'yyyymmdd')

                               AND TO_DATE ('20060531', 'yyyymmdd')

           AND ROWNUM <= 20)

SELECT *

  FROM partdata

 WHERE rowno >= 10;

分析

Oracle的分頁查詢語句基本上可以按照本文給出的格式來進行套用赏淌。
分頁查詢格式:

SELECT *

  FROM (SELECT a.*, ROWNUM rn

          FROM (SELECT *

                  FROM table_name) a

         WHERE ROWNUM <= 40)

 WHERE rn >= 21

其中最內(nèi)層的查詢SELECT * FROM TABLE_NAME表示不進行翻頁的原始查詢語句。ROWNUM <= 40和RN >= 21控制分頁查詢的每頁的范圍啄清。

上面給出的這個分頁查詢語句六水,在大多數(shù)情況擁有較高的效率。分頁的目的就是控制輸出結(jié)果集大小辣卒,將結(jié)果盡快的返回掷贾。在上面的分頁查詢語句中,這種考慮主要體現(xiàn)在WHERE ROWNUM <= 40這句上荣茫。

選擇第21到40條記錄存在兩種方法胯盯,一種是上面例子中展示的在查詢的第二層通過ROWNUM <= 40來控制最大值,在查詢的最外層控制最小值计露。而另一種方式是去掉查詢第二層的WHERE ROWNUM <= 40語句,在查詢的最外層控制分頁的最小值和最大值憎乙。這是票罐,查詢語句如下:

SELECT *

  FROM (SELECT a.*, ROWNUM rn

          FROM (SELECT *

                  FROM table_name) a)

 WHERE rn BETWEEN 21 AND 40

對比這兩種寫法,絕大多數(shù)的情況下泞边,第一個查詢的效率比第二個高得多该押。

這是由于CBO優(yōu)化模式下,Oracle可以將外層的查詢條件推到內(nèi)層查詢中阵谚,以提高內(nèi)層查詢的執(zhí)行效率蚕礼。對于第一個查詢語句,第二層的查詢條件WHERE ROWNUM <= 40就可以被Oracle推入到內(nèi)層查詢中梢什,這樣Oracle查詢的結(jié)果一旦超過了ROWNUM限制條件奠蹬,就終止查詢將結(jié)果返回了。

而第二個查詢語句嗡午,由于查詢條件BETWEEN 21 AND 40是存在于查詢的第三層囤躁,而Oracle無法將第三層的查詢條件推到最內(nèi)層(即使推到最內(nèi)層也沒有意義,因為最內(nèi)層查詢不知道RN代表什么)荔睹。因此狸演,對于第二個查詢語句,Oracle最內(nèi)層返回給中間層的是所有滿足條件的數(shù)據(jù)僻他,而中間層返回給最外層的也是所有數(shù)據(jù)宵距。數(shù)據(jù)的過濾在最外層完成,顯然這個效率要比第一個查詢低得多吨拗。

上面分析的查詢不僅僅是針對單表的簡單查詢满哪,對于最內(nèi)層查詢是復雜的多表聯(lián)合查詢或最內(nèi)層查詢包含排序的情況一樣有效婿斥。

這里就不對包含排序的查詢進行說明了,下一篇文章會通過例子來詳細說明翩瓜。

下面簡單討論一下多表聯(lián)合的情況受扳。

對于最常見的等值表連接查詢,CBO一般可能會采用兩種連接方式NESTED LOOP和HASH JOIN(MERGE JOIN效率比HASH JOIN效率低兔跌,一般CBO不會考慮)勘高。在這里,由于使用了分頁坟桅,因此指定了一個返回的最大記錄數(shù)华望,NESTED LOOP在返回記錄數(shù)超過最大值時可以馬上停止并將結(jié)果返回給中間層,而HASH JOIN必須處理完所有結(jié)果集(MERGE JOIN也是)仅乓。那么在大部分的情況下赖舟,對于分頁查詢選擇NESTED LOOP作為查詢的連接方法具有較高的效率(分頁查詢的時候絕大部分的情況是查詢前幾頁的數(shù)據(jù),越靠后面的頁數(shù)訪問幾率越锌溟埂)宾抓。

因此,如果不介意在系統(tǒng)中使用HINT的話豫喧,可以將分頁的查詢語句改寫為:

SELECT *

  FROM (SELECT a.*, ROWNUM rn

          FROM (SELECT *

                  FROM table_name) a

         WHERE ROWNUM <= 40)

 WHERE rn >= 21

————————————————
版權(quán)聲明:本文為CSDN博主「huahua.Dr」的原創(chuàng)文章石洗,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明紧显。
原文鏈接:https://blog.csdn.net/use_admin/article/details/83622414

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末讲衫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子孵班,更是在濱河造成了極大的恐慌涉兽,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篙程,死亡現(xiàn)場離奇詭異枷畏,居然都是意外死亡,警方通過查閱死者的電腦和手機虱饿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門矿辽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事■伲” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵宾娜,是天一觀的道長。 經(jīng)常有香客問我扇售,道長前塔,這世上最難降的妖魔是什么嚣艇? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮华弓,結(jié)果婚禮上食零,老公的妹妹穿的比我還像新娘。我一直安慰自己寂屏,他們只是感情好贰谣,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著迁霎,像睡著了一般吱抚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上考廉,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天秘豹,我揣著相機與錄音,去河邊找鬼昌粤。 笑死既绕,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的涮坐。 我是一名探鬼主播凄贩,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膊升!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谭企,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤廓译,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后债查,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體非区,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年盹廷,在試婚紗的時候發(fā)現(xiàn)自己被綠了征绸。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡俄占,死狀恐怖管怠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情缸榄,我是刑警寧澤渤弛,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站甚带,受9級特大地震影響她肯,放射性物質(zhì)發(fā)生泄漏佳头。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一晴氨、第九天 我趴在偏房一處隱蔽的房頂上張望康嘉。 院中可真熱鬧,春花似錦籽前、人聲如沸亭珍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽块蚌。三九已至,卻和暖如春膘格,著一層夾襖步出監(jiān)牢的瞬間峭范,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工瘪贱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留纱控,地道東北人。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓菜秦,卻偏偏與公主長得像甜害,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子球昨,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349

推薦閱讀更多精彩內(nèi)容