日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

oracle 分页_80分页查询,不止写法

發(fā)布時間:2025/3/15 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle 分页_80分页查询,不止写法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

????據(jù)孔老先生說,茴香豆的茴字有四種寫法,那oracle的分頁查詢又有多少種寫法呢?

分頁查詢,其實本質(zhì)上就是topN查詢的變種, 如果把topN的一部分結(jié)果集去掉,就變成了分頁.

topN的基本寫法,兩層select,第一層先order by,第二層再用rownum:

select owner,object_name,object_id,rownum as rn from(select?* from t1?where owner='SYS'?order by object_id desc)?where rownum<=20;

有些初級開發(fā)人員有時會寫成:

select owner,object_name,object_id,rownum as rn from?t1?where owner='SYS'? and?rownum<=20 order by object_id desc;

這種寫法的邏輯可能存在問題,因為sql解析時會先執(zhí)行rownum,隨機先選出20條記錄,再執(zhí)行排序.?而不是常見業(yè)務(wù)需要的先排序,再取前20. 如果滿足條件的全部結(jié)果集<=20, 那么邏輯也是沒問題的.

在上面topn的基礎(chǔ)上, 再套一層select, 就變成了最常見的標(biāo)準(zhǔn)的三層select的分頁查詢寫法(第一層排序,第二層給rownum取別名,得到topn,第三層去掉topn的前面部分):

select?owner,object_name,object_id,rn from

? (select a.*,rownum as rn from

? ?(select?* from t1?where owner='SYS'?order by object_id desc) a?where rownum<=20

? )?where rn>10;

執(zhí)行計劃中看到COUNT STOPKEY?為最佳(沒有sort字樣).

除了上面比較常見的寫法,?還有其他幾個不常見的寫法:

1層select(12c+才支持的offset 寫法,有時可能需要使用hint來糾正優(yōu)化器執(zhí)行計劃):

select? owner,object_name,object_id,rownum as rn

from t1

where owner='SYS'

order by object_id desc

offset 10 rows fetch next 10 rows only;

執(zhí)行計劃中看到WINDOW NOSORT STOPKEY為最佳

2層select,用到了row_number分析函數(shù)(可能需要使用hint來糾正優(yōu)化器執(zhí)行計劃):

SELECT * FROM

? (SELECT? ?owner,object_name,object_id,

? ? ? ? ? ? row_number() over (order by object_id desc) as rn

? ? ? ? ? FROM t1

? ? ? ? where owner='SYS'

)? WHERE RN<= 20 and RN > 10;

執(zhí)行計劃中看到WINDOW NOSORT STOPKEY為最佳

4層select,對于頁數(shù)比較大的分頁查詢,某些情況下可以使用:

with tmp as

(SELECT * FROM

? ? ( SELECT rid, ROWNUM as RN

? ? ? ?FROM

? ? ? ? ? ?(SELECT rowid as rid

? ? ? ? ? ? ?FROM t1

? ? ? ? ? ? ?where owner='SYS'

? ? ? ? ? ? ?order by object_id desc

? ? ? ? ? ? ) WHERE ROWNUM <= 500

? ? ) WHERE RN > 490

) select? /*+ use_nl(a) leading(b) */ owner,object_name,object_id,rn

from t1 a,tmp b

where a.rowid=b.rid;

下面的3層寫法,是比較常見的低效分頁寫法,在分頁前結(jié)果集大的情況,性能會比較差, 需要避免使用:

select * from

(

select a.*,rownum as rn??

from

(select owner,object_name,object_id

? from t1

? where owner= 'SYS'

? ?order by object_id desc

)a

) where rn>10 and rn<=20;

執(zhí)行計劃一般包含??SORT ORDER BY 的步驟.

掌握了分頁寫法,只是優(yōu)化的第一步,下面我們看一個生產(chǎn)案例,SQL代碼如下:

這是一個取topn的SQL,先取topn(分頁前結(jié)果集20萬左右),再left join,寫法完全沒問題,但是執(zhí)行時間還是比較長,需要24秒:

用hint調(diào)下執(zhí)行計劃,執(zhí)行時間變成1秒:

hint:??/*+ monitor leading(p o) push_pred(co@sel$2) */

如果再創(chuàng)建一個core_userprofile表上orgid+UpdateDate+id 3字段聯(lián)合索引, 那么這個SQL的執(zhí)行時間估計也就是10毫秒以下了. (從24秒到10毫秒,這種性能的提高,靠硬件是無法實現(xiàn)的,現(xiàn)實中確實有很多類似的SQL,可惜的是,我們很多的決策人員, 只相信高級硬件才能解決性能問題,不知道有這些高級優(yōu)化技巧)

總結(jié):

????分頁查詢,寫法只是第一步,寫法正確的基礎(chǔ)上,如果執(zhí)行計劃不佳,我們可以通過oracle優(yōu)化器提供的hint來調(diào)整執(zhí)行計劃(不需要改sql代碼); 但是如果sql寫法不佳,也是沒有辦法通過調(diào)整索引和執(zhí)行計劃進(jìn)行優(yōu)化.?

????寫法和索引,是SQL優(yōu)化的核心,在此基礎(chǔ)上通過hint調(diào)整執(zhí)行計劃, 是更高級的技術(shù), 需要更進(jìn)一步的了解優(yōu)化器特性,以人腦優(yōu)化器代替電腦優(yōu)化器.

????想提高SQL優(yōu)化技能,看完我的線上培訓(xùn)課程(索引專題,SQL寫法與改寫專題)會大有幫助.

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的oracle 分页_80分页查询,不止写法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。