遇到執行效率低下的sql語句,對于dba而言無疑是家常便飯了,但如何快速優化,把它變成小菜一碟,則得看看咱們dba+社群聯合發起人盧飛的經驗之談了。
專家簡介

盧飛
dba+社群聯合發起人
oracle 10g ocp,6年oracle資料庫維護經驗,對oracle資料庫管理、資料遷移,性能優化有着豐富的實戰經驗。目前專注于資料庫技術及自動化運維方面的研究。
在dba的工作中,sql優化的工作量占工作很大的一塊,我們在平時工作中也是這樣,常常遇到一些執行效率低下的sql語句,而這些執行效率低下的sql,有的是業務系統剛剛上線的,有的是已經執行很久但因為執行環境變化而導緻出現的。這裡給大家分享一個sql的優化案例分析。
根據我們監控系統,發現線上oltp的一個核心業務資料庫中有一條sql執行效率較慢。慢到什麼程度?半小時執行278次,平均每次28秒,占用整個db資源的56%。oltp系統中,實在太慢了。
這裡是sql執行的相關資訊。
sql優化中,有很多人總是第一要看的就是執行計劃,那麼我們就看看這條sql的執行計劃。下面可以看到單次執行3秒左右,成本為2,consistent gets較高,執行計劃中也是走index range scan。
其實單看上面的執行計劃cost還是比較低的,sql優化中,有很多人總是第一要看的就是執行計劃,但是看執行計劃一定要結合結構資訊,這裡的結構資訊就是表,索引等結構資訊及資料分布資訊。
我們先看sql語句吧。以下sql語句很簡單,且在cn字段,c_date字段上都建有索引。
表資料量約有3.6億資料。
在以上執行計劃的基礎上,根據對業務的了解,我的疑問是為什麼不走cn索引?
這裡其實可以根據謂詞條件,各自查詢 一下就能看到結果,根據cn查詢到3條,而c_date條件查詢出76w。走cn索引才對。
這裡也可以使用hint強制走cn索引看一下效果,使用hint強制走cn索引後執行時間變為毫秒級。
sql優化除了了解結構資訊(表,索引),統計資訊的準确性也很關鍵。
這裡發現最後統計資訊分析時間是5月份,相差了3個多月,是以統計資訊是不正确的。
統計資訊不準确的原因?
最終發現oracle在10g版本中預設的gather_stats_job沒有啟動,這裡啟動預設的gather_stats_job,并單獨收集一下表的統計資訊。
收集完統計資訊,這條sql的執行時間下降到毫秒級别,執行計劃已經變為idx_rec_log_cn索引的range sacn,consistent gets從原來的19409 降低到了7。效果還是很明顯。
同樣的sql又慢了,現在的執行計劃, 又開始走idx_c_log_date索引了,而且執行時間又回到了2秒, consistent gets變為10404。以下為執行計劃:
同樣我們還是先檢查統計資訊是否正确,這裡可以看到了統計資訊又不正确了,但是我們發現gather_stats_job每天都能執行成功。這是為什麼?
解決方法就是定義一個單表收集的job。
這也是為什麼大表都單獨定義收集統計資訊的原因,面試過很多的同學,基本上說出直接原因的沒有多少,都說是照着網上這麼做的。
這裡也可以看到相關的10053事件中的成本資訊,具體可以參考以下的位址了解每個類型的含義。
最終我們在業務維護時間建立了cn+c_date聯合索引後的執行計劃,至今再無類似的sql性能問題。
<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2015-11-27</b>