1

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

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

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

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

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

4

1 回答 1

1

我们中的大多数人至少 9i 及以上,并且拥有基于成本的优化器,因为 CBO 在基于规则的优化器CBO方面做得非常出色,所以压力较小。RBO

由于您使用的是 8i,因此我的建议是cardinalities正确检查。就像在性能调优中我经常说的那样,这都是关于基数的

请注意,a FTS,即全表扫描并不总是不好的。当您想要获取超过 10-15% 或更多的行时,optimizer宁愿估计执行计划以从数据块中随机选择行,而不是使用Index. 索引是有目的的,在检索数据时并不总是有帮助。有关更深入的详细信息,只需搜索“为什么不使用我的索引”。

于 2014-09-29T17:08:12.303 回答