2015-12-01 26 views
2

這對我來說是一個重新發生的問題。我有一段時間運行良好的表述,一段時間後優化器決定選擇另一個執行計劃。這甚至發生在我查詢一個(複合)主鍵時。爲什麼優化器選擇成本更高的執行計劃?

當我在dba_hist_sql_plan中查找執行計劃時,使用主鍵索引顯示成本爲20,查詢執行全表掃描的成本爲270。

plan_hash_value Operation  Options    Cost Search_Columns 

2550672280 0 SELECT STATEMENT      20 
2550672280 1 PARTITION HASH SINGLE    20 
2550672280 2 TABLE ACCESS  BY LOCAL INDEX ROWID 20 
2550672280 3 INDEX   RANGE SCAN   19    1 

3908080950 0 SELECT STATEMENT      270 
3908080950 1 PARTITION HASH SINGLE    270 
3908080950 2 TABLE ACCESS FULL     270 

我已經注意到,優化器僅使用在主鍵索引中的第一列,然後再執行範圍掃描。但我真正的問題是:爲什麼優化器選擇成本更高的執行計劃?這不是兩個執行計劃同時使用,我注意到一個快照內的交換機,然後它保持這樣的幾個小時/天。所以它不能成爲綁定窺視的問題。

我們目前的解決方案是,我打電話給我們的DBA,並刷新語句緩存。但這不是真正可持續的。

編輯: SQL看起來像這樣:select * from X where X.id1 =?和X.id2 =?和X.id3 =? 與(id1,id2,id3)是表上的複合主鍵(具有唯一索引)。

+0

可能有很多原因。其中一些是有效的。最常見的一個是當exec。計劃適用於其他模式。另一個原因可以是動態採樣或性能基準。 – ibre5041

+0

SQL在哪裏?你看**自適應光標共享**嗎? –

+0

SQL很簡單。像「select * from x where x.id1 =?and x.id2 =?and x.id3 =?」 – EasterBunnyBugSmasher

回答

0

最有可能的聚類因子和指數的瑕疵可能非常高。通過查詢dba_indexes來檢查blevel。如果blevel大於3,請嘗試重建索引。

同時檢查爲主鍵創建的索引是否唯一。按照計劃,它使用範圍掃描而不是唯一掃描。該指數很可能不是唯一的。

+1

性能不佳的索引可以解釋爲什麼全表掃描優於索引掃描。但是,這不應該反映在成本上,還是使用最低成本的計劃? –

+0

該指數是唯一的。我理解它的方式:範圍掃描是優化器僅處理第一列索引的結果。 blevel是2,clustering_factor是這個表的一個大問題,並且變化很大。 – EasterBunnyBugSmasher

1

也許它與Oracle 11g上的一個錯誤有關。
錯誤18377553

AAAAAAAAAAAAAAAAAAAAmyvalue 
AAAAAAAAAAAAAAAAAAAAsomeohtervalue 
AAAAAAAAAAAAAAAAAAAAandsoon 
B1234 

直方圖起不到很好的:與直方圖和值> 32字節

當你的數據是像窮人基數估算。

該解決方案禁用直方圖上的主鍵,所有將開始工作順利。

+0

非常有趣的錯誤。我們的複合主鍵包括(以此順序):1)來自序列的ID,最大值:約700K,分佈大致相同2)日期代表2000到2018年之間的一天。在大多數情況下,我們有365到3650個不同的天數爲一個ID。 3)表示行被邏輯刪除的日期,因此在約95%的行中,這代表「我們」的無限未來。 – EasterBunnyBugSmasher

+0

和日期是7字節?所以我們沒有> 32字節的值。我會理解,如果優化器只選擇前兩列進​​行搜索,因爲95%的情況下他只獲得1行。但在第一列之後停下來很奇怪 – EasterBunnyBugSmasher

0

顯然,優化程序不能正確顯示有關類型轉換的成本。此問題的根本原因是日期值的類型映射不正確。雖然數據庫中的列是DATE類型,但JDBC類型錯誤地爲java.sql.Timestamp。要將DATE列與Timestamp搜索參數進行比較,需要先將表中的所有值先傳輸到Timestamp。這是額外的成本,並使索引不可用。