一次ORACLE SQL謂詞跨界導致的執行計劃不準

gaopengtttt發表於2015-08-28
一次ORACLE SQL謂詞跨界導致的執行計劃不準


首先說明謂詞跨界一般出現在日期型別中,打個比方你的統計資料是8月20號的,但是今天是8月28日,在這20號到28號之間日期是沒有進入統計資料的,
這樣可能導致,根據統計資訊計算出來的COST異常的小,這樣可能導致本來該走其他欄位索引的語句走到時間索引上去,導致執行計劃最終錯誤。
在10053中可以看到如下提示:


as selectvity of out-of-range/non-existent value pred


以前多次遇到過,今天再次遇到,就記錄於此,如下SQL
select *
from test
where seller_user_id = '123'
and raw_add_time >= trunc(sysdate-1, 'mi')
and raw_add_time < trunc(sysdate, 'mi')


其執行計算如下:
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 2023568823
--------------------------------------------------------------------------------
| Id  | Operation                    | Name                   | Rows  | Bytes |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                        |     1 |   574 |
|*  1 |  FILTER                      |                        |       |       |
|*  2 |   TABLE ACCESS BY INDEX ROWID| TEST                   |     1 |   574 |
|*  3 |    INDEX RANGE SCAN          | TEST_ADD_TIME_INDEX    |     2 |       |
--------------------------------------------------------------------------------
這裡test_ADD_TIME_INDEX就是我的時間上的索引,透過檢視選擇率後發現seller_user_id遠遠
小於raw_add_time範圍的選擇率,應該走到seller_user_id上的索引才對,這裡可能發生了
謂詞跨界檢視其統計資料發現是7月20號的,今天是8月28日。然後進行了一下驗證


調整時間後
select *
from test
where seller_user_id = '123'
and raw_add_time >= trunc(sysdate-100, 'mi')
and raw_add_time < trunc(sysdate-99, 'mi')




PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 576270446
--------------------------------------------------------------------------------
| Id  | Operation                    | Name                 | Rows  | Bytes | Cos
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |                      |     1 |   574 |
|*  1 |  FILTER                      |                      |       |       |
|*  2 |   TABLE ACCESS BY INDEX ROWID| TEST_BASE_INFO       |     1 |   574 |
|*  3 |    INDEX RANGE SCAN          | TEST_ID_INDEX |    23 |       |
--------------------------------------------------------------------------------


這裡更改了時間範圍在已知的統計資料範圍內,執行計劃正確。


我們進行10053 TRACE驗證:


SINGLE TABLE ACCESS PATH 
  Single Table Cardinality Estimation for TEST[TEST] 
  Column (#14): 
    NewDensity:0.000001, OldDensity:0.000623 BktCnt:254, PopBktCnt:79, PopValCnt:7, NDV:814912
  Column (#14): SELLER_USER_ID(
    AvgLen: 21 NDV: 814912 Nulls: 855565 Density: 0.000001
    Histogram: HtBal  #Bkts: 254  UncompBkts: 254  EndPtVals: 183


  Column (#41): RAW_ADD_TIME(
    AvgLen: 8 NDV: 13533184 Nulls: 0 Density: 0.000000 Min: 2454768 Max: 2457225
  Using prorated density: 0.000000 of col #41 as selectvity of out-of-range/non-existent value pred //謂詞跨界
  Table: TEST  Alias: TEST
    Card: Original: 27510606.000000  Rounded: 1  Computed: 0.00  Non Adjusted: 0.00
  Access Path: TableScan
    Cost:  618899.27  Resp: 618899.27  Degree: 0
      Cost_io: 616819.00  Cost_cpu: 43729541941
      Resp_io: 616819.00  Resp_cpu: 43729541941
  Using prorated density: 0.000000 of col #41 as selectvity of out-of-range/non-existent value pred //謂詞跨界
  Access Path: index (RangeScan)
    Index: TEST_ADD_TIME_INDEX 
    resc_io: 5.00  resc_cpu: 39819
    ix_sel: 0.000000  ix_sel_with_filters: 0.000000 
    Cost: 5.00  Resp: 5.00  Degree: 1
 
 謂詞跨界後選擇率成為了0.000000,這樣導致了執行計劃錯誤。
 解決也很簡單,按需求重新收集統計資訊即可
 

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

相關文章