ORACLE - 未在连接中使用的索引

时间:2014-09-29 16:28:42

标签: oracle oracle8i

我很难理解为什么在我的一个查询中没有使用我的索引。

我对以下两个查询没有任何问题。第一个在这里

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 

然后我编写第三个查询,这或多或少是前两个查询的连接:

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”的表(对于机密性问题)实际上是一个物化视图。

感谢您的回答/问题/建议。

(如果编辑不是最佳的,请原谅我,第一次在这里发帖)。

1 个答案:

答案 0 :(得分:1)

我们大多数至少9i及以上,并且CBO,即基于成本的优化器,由于CBO在基于规则的优化器RBO上做得非常出色,因此紧张程度较低。

因为你是8i,我的建议是正确检查cardinalities。正如性能调整一样,我总是说, 所有关于基数

请注意,FTS,即全表扫描并不总是坏的。当您想要获取超过10-15%或更多行时,optimizer宁可 估算 执行计划 从数据块中随机选择行,而不是使用Index。索引是出于某种目的,在检索数据时并不总是有用。有关详细信息,请搜索“ 为什么我的索引未被使用 ”。