通過鎖定表的統計資訊來穩定sql的執行計劃

zhang41082發表於2019-03-24

問題提出:
兩個表的關聯查詢,一個表資料量在千萬,一個表資料量只有幾條(參數列),大表是按時間進行的分割槽表,而且時間欄位上還建有分割槽索引。剛開始,執行計劃是正確的,但是後來卻發現兩個表的關聯不是走分割槽表的索引,而是直接掃描整個分割槽,有點費解。

[@more@]

瞭解業務後發現,參數列中有兩個欄位,一個是起始時間,一個是終止時間,這兩個時間間隔一般在10分鐘。每過一段時間,將拿參數列中的時間出來,然後根據時間段去大表中查詢這段時間內進行的業務。大表每天新增資料在20萬左右,10天一個分割槽,小表資料量不變,變的只是裡面的開始和結束時間,但結束-開始基本都在10分鐘左右。
因此應該是oracle不知道小表中的開始和結束時間的具體值,所以它不能使用這個值去進行成本估算,因此覺得掃描索引再從表讀取資料還沒有直接全掃描分割槽來的快。於是對錶的column值進行分析,讓oracle能知道其中的值的分佈。analyze table tab compute statistics for column,執行上面分析後,再來檢視執行計劃,分割槽掃描變成了讀取索引了,而且查詢速度也提升不少。可是小表的資料是隨時間頻繁變化的,而且oracle會自動收集表的統計資訊,導致執行計劃再次出現問題。看了半天STORED OUTLINES也沒整大明白怎麼來固定一個sql的執行計劃,而且動作比較大。
採用鎖定統計資訊的方法,呼叫dbms_stats.lock_table_stats包,把小表統計資訊鎖定,問題得到解決。

總結:在10G中,oracle會自動收集表的統計資訊,大部分情況下,這種行為是有利的,不需要對某個表做收集的時候,可以採用鎖定統計資訊的方法,把不需要收集的表排除在外,使得此表上的sql的執行計劃得到穩定。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25016/viewspace-927548/,如需轉載,請註明出處,否則將追究法律責任。

相關文章