天天看點

rownum應用系列之分頁查詢--續1

昨天的思考題,老虎劉的建議是:

建立col_1和col_2字段上的聯合索引,避免排序,提高效率。聯合索引的字段順序不能錯,order by的字段要放在聯合索引的最後。如果是order by desc,正常情況優化器會自動使用index descending掃描方式,不需要建索引的時候加desc 。也有sql複雜的時候優化器沒有使用index descending掃描方式,則可以用index_desc來糾正。

今天剛好遇到一個分頁查詢的問題SQL,簡化如下:

SELECT *

FROM (

SELECT

......

,ROWNUM RNSTART

FROM S_SRV_REQ SSR

WHERE SSR.ACT_OPEN_DT + 1 / 3 >= SYSDATE - 60 AND

ROWNUM <= 10 ORDER BY SSR.CREATED DESC

) T

WHERE T.RNSTART >= 1;

這個SQL有兩個問題:

1、分頁查詢的寫法有問題,rownum 與 order by并列同時出現在同一個where後面,這種寫法得到的結果可能是亂序(除非使用CREATED字段上索引的降序掃描,但是如果該索引不可用,得到的結果就不對了),需要按照上一篇文章的寫法進行改寫。

2、謂詞條件SSR.ACT_OPEN_DT + 1 / 3 >= SYSDATE - 60過濾性很好,而且存在ACT_OPEN_DT字段上的索引,但是因為字段上存在表達式 “+1 / 3“,導緻索引不能使用,需要改寫sql,将 SSR.ACT_OPEN_DT + 1 / 3 >= SYSDATE - 60 改成SSR.ACT_OPEN_DT >= SYSDATE - 60 - 1 / 3。

注:

因為謂詞條件不是等值條件(昨天的sql是col_1= :b1,今天是col_x >=),這個sql如果建立ACT_OPEN_DT和CREATED聯合索引是沒有意義的,這種情況還是隻會使用索引的第一個字段,無法避免排序。