Oracle 优化器不接受索引提示
Posted
技术标签:
【中文标题】Oracle 优化器不接受索引提示【英文标题】:Oracle optimizer is not accepting index hint 【发布时间】:2013-03-14 11:37:10 【问题描述】:当我运行合并查询时,索引无法读取并且查询运行速度很慢,请告诉我。
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'
提前致谢
【问题讨论】:
explain plan
说什么?
请查看您的帖子。您在索引中列出的列与代码中的列不匹配(它们已切换)。
MAP_RBC_ETL.ANNEXURE
、MAP_RBC_ETL.FREE_CODE_9
或 STAGE_DIM_ACCOUNTS.RBC_CODE
是否可以为空?如果是,哪些可以为空,哪些不能?
【参考方案1】:
优化器足够聪明,知道您的索引是无用的。
如果free_code
上的大多数值是“0”或“NA”,则该列中的索引可能很有用。由于您没有提供有关数据量或分布的任何信息,我们无法确定。但是您对map_rbc_etl
有其他限制条件,因此无论如何数据库都需要转到表中。我的猜测是优化器选择在 map_rbc_etl 上使用全表扫描,因为这比大量索引读取要快。
这是因为索引读取是两个操作 - 读取索引,读取行。因此,只有当读取的行的 百分比 很小时,它才会派发红利。否则,读取所有行并将它们筛选到内存中会更有效。
这是调优的“秘密”:索引读取并不总是更快;全表扫描并不总是坏事。
类似的逻辑适用于读取stage_dim_accounts
。索引列不太可能是选择性的。除非...除非map_rbc_etl
中的行数非常少并且仅匹配stage_dim_accounts
中的一小部分行。我之前对数据指标的评论再次适用。
【讨论】:
【参考方案2】:要使用的索引 在 map_rbc_etl(free_code_9,附件) 在 stage_dim_accounts(rbc_code) 上;
现在这些可能由于先前答案中的原因而无法使用。 可能不使用索引的其他原因是: 1. 优化器认为不使用索引会更有效。 2. 如果列在视图中并且在列上有函数调用。要使用此使用基于函数的索引。 3.你在查询中进行数学运算。请注意,您可以查看解释计划并创建索引以匹配其加载行的方式。 4. 在 where 子句中将列连接在一起。使用基于函数的索引来克服这一点。 5. 您没有在语句的 where 子句中包含连接索引中的第一列。请注意,Oracle 9i 或更高版本会跳过扫描并且可以使用索引。 6.你使用or子句。在这种情况下,最好为除 or 子句之外的所有子句创建一个索引,并为每个 or 值创建一个索引,然后它将适当地使用所有索引。
如果您不知道如何使用基于函数的索引,可以使用 where 子句中的 to_upper() 示例
create indexName on tableName(to_upper(colname));
任何 oracle sql 函数(内置的或用户创建的)都可以在索引中。
【讨论】:
以上是关于Oracle 优化器不接受索引提示的主要内容,如果未能解决你的问题,请参考以下文章