【问题标题】:Wrong index is chosen by OracleOracle 选择了错误的索引
【发布时间】:2012-01-02 22:02:42
【问题描述】:

我在 Oracle 中建立索引时遇到问题。将尝试用一个实例来解释我的问题,如下所示。

我有一个包含 A、B、C、D 列的表 TABLE1 另一个包含 A、B、C、E、F、H 列的表 TABLE2

我已经为 TABLE1 创建了索引

IX_1 A
IX_2 A,B
IX_3 A,C
IX_4 A,B,C

我已经为 TABLE1 创建了索引

IY_1 A,B,C
IY_2 A

当我提出类似的查询时

SELECT * FROM TABLE1 T1,TABLE2 T2
WHERE T1.A=T2.A

当我给出解释计划时,我得到的不是 IX_1 也不是 IY_2

它需要 IX_4 和 IY_1

为什么没有选择正确的索引?

已编辑:

谁能帮我了解 INDEX RANGE SCAN、INDEX UNIQUE SCAN、INDEX SKIP SCAN 之间的区别

我猜 SKIP SCAN 的意思是当 Oracle 在复合索引中跳过一列时

我不知道的其他人呢!

【问题讨论】:

  • 在使用索引方面没有正确错误。 Oracle 根据其成本计算选择最优的执行计划。您最近是否更新了数据库统计信息?此外,我不明白为什么你有这么多索引。如果改为使用 IX_4 和 IY_2,则所有可能受益于 IX_1、IX_2 或 IY_2 的查询都可以以非常相似的成本和执行计划执行。
  • 谢谢科多。我没有创建这些索引。我们正在 JAROSODS 数据库上实现。他们有足够的索引。我试图模仿我的问题。我也无权更改这些索引。只是为了使用它们
  • @Codo >> 你的意思是说我们不能手动更改成本计算?还有你所说的数据库统计是什么意思?
  • Oracle 要计算查询计划的成本,它需要知道一张表有多少行,某些值的频率等。这些统计数据需要使用 DBMS_STATS 包定期计算。否则 Oracle 会使用低效的执行计划。而且我不明白您为什么要更改成本计算?那有什么好处呢?你问这个问题的目的是什么?您发布的查询是否存在性能问题?
  • 对不起 Codo,我想在解释我的问题时有点含糊。实际上,在我的查询中,我使用的 where 子句与索引中的完全一样。但是没有选择该索引,它正在选择其他索引并且执行 INDEX SKIP SCAN (Cost is too high) 。但如果我按照 Florin Ghita 的建议去做,成本就会降低很多。抱歉,实际上我的意思是说我想降低成本而不是改变成本

标签: oracle oracle11g indexing oracle10g


【解决方案1】:

索引的最大好处是您可以从表中选择几行,而无需扫描整个表。 如果您要求太多行(假设 30% - 取决于很多事情),引擎将更愿意扫描整个表以查找这些行。 那是因为使用索引读取行会产生开销:读取一些索引块,然后读取表块。

在您的情况下,为了连接表 T1 和 T2,Oracle 需要这些表中的所有行。读取(完整)索引将是一个不安全的操作,增加了不必要的成本。

更新:向前迈出一步:如果你运行:

SELECT T1.B, T2.B FROM TABLE1 T1,TABLE2 T2
WHERE T1.A=T2.A

Oracle 可能会使用索引(IX2,IY2),因为它不需要从表中读取任何内容,因为值 T1.B,T2.B, 在索引中。 p>

【讨论】:

  • 但我能知道 INDEX RANGE SCAN、INDEX UNIQUE SCAN、INDEX SKIP SCAN 之间的区别
  • 是的弗洛林你说的是对的!!通过在查询中选择选定的列,我可能会丢失 COST 差异。谢谢...抱歉,如果我错了,为什么如果我在 select query 中添加不在索引中的另一列,我的成本会发生变化
  • 在第 62 页您可以找到解释:google.ro/…
  • 第二个问题你可以查看我回复的最后一句:如果这些值在索引中,则不会从表中读取它们,因此成本较低。
猜你喜欢
  • 2015-08-03
  • 1970-01-01
  • 1970-01-01
  • 2017-10-24
  • 2014-04-18
  • 2016-05-03
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多