2014-04-01 41 views
2

我有一個查詢使用日期索引,如果我查詢的是1,2,3,4或5天的數據。對於這些查詢數據在不到10秒的時間內回來。在6天或更長時間內,它決定不使用索引,如果查詢完全恢復,查詢將永久使用。如果我嘗試使用索引幫助,它似乎沒有使用索引。我嘗試在索引和桌面上進行收集統計。下面是該查詢(9天的數據,在這種情況下):爲什麼查詢不在Oracle中使用索引

select 

         r.range_text as duration_range, 
         nvl(count(c.call_duration),0) as calls, 
         nvl(SUM(call_duration),0) as total_duration 
        from 
         duration_ranges r 
        left join 
         big_table c 
        on c.call_duration >= r.range_lbound AND c.call_duration <= r.range_ubound 

        where calltimestamp_local >= to_date('20-02-2014 00:00:00','dd-MM-yyyy HH24:mi:ss') 
        and calltimestamp_local <= to_date('28-02-2014 23:59:59' ,'dd-MM-yyyy HH24:mi:ss') 
        and c.destinationnumber = 'sip:[email protected]:5060;user=phone' 
        group by 
        r.range_text 
       order by 
        r.range_text; 

這裏是沒有指標的解釋計劃:

Without Index 
SELECT STATEMENT ALL_ROWSCost: 827,605 Bytes: 1,344 Cardinality: 14       
    8 SORT GROUP BY Cost: 827,605 Bytes: 1,344 Cardinality: 14     
     7 MERGE JOIN Cost: 827,486 Bytes: 246,552,768 Cardinality: 2,568,258     
      2 SORT JOIN Cost: 4 Bytes: 308 Cardinality: 14   
       1 TABLE ACCESS FULL TABLE MYDB.DURATION_RANGES Cost: 3 Bytes: 308 Cardinality: 14   
      6 FILTER    
       5 SORT JOIN Cost: 827,471 Bytes: 14,164,118 Cardinality: 191,407   
        4 PARTITION RANGE ALL Cost: 824,134 Bytes: 14,164,118 Cardinality: 191,407 Partition #: 7 Partitions accessed #1 - #1653 
         3 TABLE ACCESS FULL TABLE MYDB.BIG_TABLE Cost: 824,134 Bytes: 14,164,118 Cardinality: 191,407 Partition #: 7 Partitions accessed #1 - #1653 

隨着指數:

With Index 
Plan 
SELECT STATEMENT ALL_ROWSCost: 822,732 Bytes: 1,344 Cardinality: 14       
    8 SORT GROUP BY Cost: 822,732 Bytes: 1,344 Cardinality: 14     
     7 MERGE JOIN Cost: 822,635 Bytes: 205,460,736 Cardinality: 2,140,216     
      2 SORT JOIN Cost: 4 Bytes: 308 Cardinality: 14   
       1 TABLE ACCESS FULL TABLE MYDB.DURATION_RANGES Cost: 3 Bytes: 308 Cardinality: 14   
      6 FILTER    
       5 SORT JOIN Cost: 822,621 Bytes: 11,803,444 Cardinality: 159,506   
        4 TABLE ACCESS BY GLOBAL INDEX ROWID TABLE MYDB.BIG_TABLE Cost: 819,841 Bytes: 11,803,444 Cardinality: 159,506 Partition #: 7 Partition access computed by row location 
         3 INDEX RANGE SCAN INDEX MYDB.IDX_CDR_CALLTIMESTAMP_LOCAL Cost: 2,744 Cardinality: 850,691 

任何想法爲什麼它不使用索引如果在5天的價值數據它快速回來?它似乎沒有優化的東西,因爲它回來要慢得多。

+0

順便說一句,版本是Oracle數據庫11g企業版版本11.2.0.3.0 - 64位生產 – urbanmojo

回答

0

也許它工作速度較慢,因爲數據和索引不會有太大變化?您可以通過強制Oracle使用索引來輕鬆檢查它 - 指定INDEX提示,然後將索引與索引進行比較,如果沒有索引,則執行相同的查詢。

您還可以指定NOINDEX提示將時間比較爲5天或更少。

+0

我試過索引提示,但似乎沒有工作。它應該如下,對嗎? (其中IDX_CDR_CALLTIMESTAMP_LOCAL是索引名) '選擇 /* +指數(BIG_TABLE IDX_CDR_CALLTIMESTAMP_LOCAL)*/ r.range_text作爲duration_range, NVL(計數(c.call_duration),0)作爲呼叫, NVL(SUM (call_duration),0)as total_duration from ....等' – urbanmojo

+0

@ user2281976如果你在表中使用別名,那麼你可能應該在提示中使用它:'select/* + index(c IDX_CDR_CALLTIMESTAMP_LOCAL)* /。 ..' – psur

+0

以爲我試過 - 猜我沒有。是的,必須使用別名。對於6天的價值數據,如果我強制使用索引,它會更好,但仍然比5天慢得多。如果我在選擇中選擇1-5天,只需不到10秒,則需要6天(強制索引使用),只需2分鐘。如果我嘗試了6天沒有日期索引的數據,它會運行很長時間。 – urbanmojo

相關問題