目前項目組中的 分頁語句, 存在 很大問題, 按照 道理來說 分頁語句首頁 都不會很慢的。 結果應該是 秒出的。 但我們項目組中 的分頁, 哥首次優化時候, 出現35S, 這個肯定不行的。
SQL 涉及到保密問題, 簡寫
select b.*
from (select rownum as r, a.*
from (select smzor.AREA_NAME, **************************
from ST_MNTR_ZD_ORDER_REPORT smzor, dim_area da
where smzor.local_area_id = 3
and smzor.area_id = da.area_id
order by smzor.HWY_RETURN_FLAG desc,
smzor.HWY_RETURN_DT desc nulls last) a) b
where b.r >= 1
and b.r <= 20;
哥一看 這個SQL, 發現 dim_area 這個表莫, 很明顯 這個 過濾數據用的, 測試下 果然 是的, 這個表 對於的數據是 n:1, 而且 select 後面的數據都是 zmzor 中的。
所以 一看 改成 半連接, 再一看 order by 我靠啥需求, 明顯的全表掃描, 而且還是 desc 排序, 而且還是 null 最後。關鍵的是 媽的 最後 r>=1 , r<20 , 這個肯定不合理, 要想 排序 秒出, 必須建索引了, 索引見起來 還得慎重,
哥考慮 再三 結果 建索引 idx_lhd ( local_area_id , HWY_RETURN_FLAG desc, HWY_RETURN_DT, 0 )
select b.*
from (select rownum as r, a.*
from (select /*+ index( idx_lhd smzor ) */ smzor.AREA_NAME, **************************
from ST_MNTR_ZD_ORDER_REPORT smzor
where smzor.local_area_id = 3
and smzor.area_id = da.area_id
and exists ( select /*+ no_unnest */ 1 from dim_area da where smzor.area_id = da.area_id )
order by smzor.HWY_RETURN_FLAG desc,
smzor.HWY_RETURN_DT desc nulls last) a) b
where b.r >= 1
and b.r <= 20;
覈對數據, 前後數據一致, 但前面的 35s 左右, 後面的 0.12s 左右 。
兩次的計劃
前後數據對比發現 前面掃了 很多很多, 後面 掃了 10條, 所以 哥這個改寫 結果秒出了。。。。。 吼吼.......
哥當時的思路是 先是小表 驅動大表, 運用 試圖推入 吧 rownum<=10 推入到掃描中, 建索引, 利用索引的有序性, 掃描數據, 如何建索引, 關鍵是看 過濾條件和 連接條件。 結果哥寫了 好多的hint 發現 很難寫出這個理想的hint, 後來 把SQL拆掉 搞了, 發現 只有 去掉 髒數據 過濾 條件 速度才提高上來。 於是哥想到了 no_unnest 這個hint 結果 給解了, 看來哥要 好好理解 這個hint 了.... 確實有用的 。。。。
哥一直努力的方向........................SQL 優化。