Oracle优化器不接受索引提示

时间:2013-03-14 11:37:10

标签: performance oracle plsql query-optimization

当我运行合并查询时,索引无法读取,查询运行速度很慢请告诉我。

stage_dim_accounts中的索引(rbc_code)

map_rbc_etl(free_code_9)中的索引

MERGE INTO stage_dim_accounts t 
USING map_rbc_etl s ON (t.rbc_code = s.free_code_9)
WHEN MATCHED THEN UPDATE 
SET t.indx_no= s.indx_no  
WHERE s.annexure= 'AXN-I' 
AND (.free_code_9 <> 'NA' AND s.free_code_9   <> '0') 
AND t.rbc_code <> 'NA'

提前致谢

2 个答案:

答案 0 :(得分:3)

优化器足够聪明,知道你的索引是无用的。

如果该列中的大多数值为“0”或“NA”,free_code上的索引可能会有用。由于您没有提供有关数据量或分布的任何信息,我们无法分辨。但是您在map_rbc_etl上有其他限制条件,因此数据库无论如何都需要转到表格。我的猜测是,优化器选择在map_rbc_etl上使用全表扫描,因为这比大量的索引读取更快。

这是因为索引读取是两个操作 - 读取索引,读取行。因此,如果读取的行的百分比很小,它只会支付股息。否则,读取所有行并将其存储在内存中会更有效。

以下是调整的重要“秘诀”:索引读取并不总是更快;全表扫描并不总是坏事。

类似的逻辑适用于阅读stage_dim_accounts。索引列不太可能具有选择性。除非......除非map_rbc_etl中的行数非常小且只匹配stage_dim_accounts中的少量行。我之前对数据指标的评论再次适用。

答案 1 :(得分:0)

要使用的索引 在map_rbc_etl上(free_code_9,附件) 并在stage_dim_accounts(rbc_code);

现在这些可能不会被用于之前答案中的原因。 不能使用索引的其他原因是: 1.优化器决定不使用索引更有效。 2.如果列在视图上并且在列上具有函数调用。要使用此功能的索引。 3.在查询中执行数学运算。请注意,您可以查看说明计划并创建索引以匹配加载行的方式。 4.在where子句中将列连接在一起。使用基于函数的索引来克服这个问题。 5.您的语句的where子句中的连接索引中不包含第一列。请注意,Oracle 9i或更高版本会跳过扫描并可以使用索引。 6.您使用或条款。在这种情况下,最好为除了or子句之外的所有子句创建一个索引,为每个或者值创建一个索引,然后它将适当地使用所有索引。

如果您不知道如何使用基于函数的索引,则在where子句中使用以下的to_upper()示例

create indexName on tableName(to_upper(colname));

任何oracle sql函数(内置或用户创建)都可以在索引中。