2014-09-29 51 views
1

我頭痛的理解爲什麼我的索引沒有在我的某個查詢中使用。ORACLE - 未在加入中使用的索引

我對以下兩個查詢沒有問題。這裏的第一個

SELECT XHHA.* , XSAIL.* 
FROM TABLE_A XSAIL, 
xxd_hist_headers_all XHHA 
WHERE XSAIL.id = 'XXXX' 
AND XHHA.CONTRACT_NUMBER = XSAIL.CONTRACT_NUMBER 
AND XHHA.history_flag = 'VALID' 
AND XHHA.buff_flag  = 'N' 

讓我在這裏我們可以看到使用索引以下執行計劃:

Plan 
SELECT STATEMENT CHOOSECost: 451 Bytes: 1 332 628 342 Cardinality: 4 087 817    
    5 NESTED LOOPS Cost: 451 Bytes: 1 332 628 342 Cardinality: 4 087 817   
     2 TABLE ACCESS BY INDEX ROWID APPS.TABLE_A_N1 Cost: 1 Bytes: 266 911  Cardinality: 2 999 
     1 INDEX RANGE SCAN NON-UNIQUE APPS.TABLE_A_N1 Cost: 1 Cardinality: 2 999 
    4 TABLE ACCESS BY INDEX ROWID XXD.XXD_HIST_HEADERS_ALL Cost: 1 Bytes: 32 304 522 Cardinality: 136 306  
     3 INDEX RANGE SCAN NON-UNIQUE XXD.XXD_HIST_HEADERS_N1 Cost: 2 Cardinality: 136 306 

第二個請求如下:

SELECT XHHA.*, XPHA.* 
FROM 
xxd_hist_headers_all XHHA, 
XXD_POLICY_HIST_ALL XPHA 
WHERE XHHA.CONTRACT_NUMBER = 'XXXX' 
AND XHHA.history_flag = 'VALID' 
AND XHHA.buff_flag  = 'N' 
AND XPHA.CONTRACT_NUMBER = XHHA.CONTRACT_NUMBER 

給了我下面的執行計劃,其中我們仍然看到索引被使用:

Plan 
SELECT STATEMENT CHOOSECost: 2 Bytes: 302 Cardinality: 1    
5 NESTED LOOPS Cost: 2 Bytes: 302 Cardinality: 1   
    2 TABLE ACCESS BY INDEX ROWID XXD.XXD_POLICY_HIST_ALL Cost: 1 Bytes: 65 Cardinality: 1  
     1 INDEX UNIQUE SCAN UNIQUE XXD.XXD_POLICY_HIST_U1 Cost: 2 Cardinality: 2 
    4 TABLE ACCESS BY INDEX ROWID XXD.XXD_HIST_HEADERS_ALL Cost: 1 Bytes: 237 Cardinality: 1  
     3 INDEX RANGE SCAN NON-UNIQUE XXD.XXD_HIST_HEADERS_N1 Cost: 2 Cardinality: 1 

然後我寫這篇文章的第三查詢,這或多或少的加入了2分前幾次:

SELECT XHHA.* , XSAIL.*, XPHA.* 
FROM TABLE_A XSAIL, 
xxd_hist_headers_all XHHA, 
XXD_POLICY_HIST_ALL XPHA 
WHERE XSAIL.id = 'XXXX' 
AND XHHA.CONTRACT_NUMBER = XSAIL.CONTRACT_NUMBER 
AND XHHA.history_flag = 'VALID' 
AND XHHA.buff_flag  = 'N' 
AND XPHA.CONTRACT_NUMBER = XHHA.CONTRACT_NUMBER 

沒有更多的索引使用,完全掃描的3個表涉及的2:

Plan 
SELECT STATEMENT CHOOSECost: 9 695 Bytes: 2 014 546 788 Cardinality: 4 145 158   
6 HASH JOIN Cost: 9 695 Bytes: 2 014 546 788 Cardinality: 4 145 158   
    2 TABLE ACCESS BY INDEX ROWID APPS.TABLE_A_N1 Cost: 1 Bytes: 551 816 Cardinality: 2 999 
     1 INDEX RANGE SCAN NON-UNIQUE APPS.TABLE_A_N1 Cost: 1 Cardinality: 2 999 
    5 HASH JOIN Cost: 9 004 Bytes: 41 741 836 Cardinality: 138 218 
     3 TABLE ACCESS FULL XXD.XXD_POLICY_HIST_ALL Cost: 114 Bytes: 18 903 625 Cardinality: 290 825 
     4 TABLE ACCESS FULL XXD.XXD_HIST_HEADERS_ALL Cost: 821 Bytes: 32 757 903 Cardinality: 138 219 

您是否看到有任何理由不在第三個請求中使用索引? 如果這有什麼影響,我重命名爲「TABLE_A」(用於保密問題)的表格實際上是一個物化視圖。

謝謝你的回答/問題/建議。

(請原諒,如果編輯不是最佳的,第一次發佈在這裏)。

+0

可能很重要,這是運行在一個古老的Oracle 8i上......但是我無能爲力:( – Tontonmox 2014-09-29 16:30:01

回答

1

我們大多數人至少9i及以上,並有CBO,即基於成本的優化器,因爲CBO在RBO(即基於規則的優化器)方面做得很出色,所以它們的緊張程度較低。

因爲,你在8i,我的建議是正確檢查cardinalities。正如在性能調整我總是說,這是關於基數

請注意,FTS,即全表掃描並不總是不好。當你想獲取不止,可以說〜10-15%或更多行時,optimizer寧願估計執行計劃隨機挑行從數據塊,而不是使用Index。索引是爲了一個目的,並不總是幫助檢索數據。有關更深入的詳細信息,只需搜索「爲什麼我的索引不被使用」。

+0

)你的回答讓我在基數正確的方式上完成了查詢的物化視圖。 ,當我想到基數時,我注意到沒有分析過它運行 在物化視圖上運行分析後,索引現在可以正確使用了,我的性能如我所料。 – Tontonmox 2014-09-30 08:25:27

+0

感謝您的反饋。我說***「這是關於基數」***。祝你好運! – 2014-09-30 08:33:53