【问题标题】:Oracle optimizer is not accepting index hintOracle 优化器不接受索引提示
【发布时间】: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.ANNEXUREMAP_RBC_ETL.FREE_CODE_9STAGE_DIM_ACCOUNTS.RBC_CODE 是否可以为空?如果是,哪些可以为空,哪些不能?

标签: performance oracle plsql query-optimization


【解决方案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 函数(内置的或用户创建的)都可以在索引中。

    【讨论】:

      猜你喜欢
      • 2015-11-20
      • 2020-01-22
      • 2019-08-27
      • 2016-08-03
      • 2018-09-22
      • 1970-01-01
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      相关资源
      最近更新 更多