【问题标题】:Full table scan when querying against an indexed column查询索引列时的全表扫描
【发布时间】:2012-02-04 09:13:54
【问题描述】:

我为一个表创建了一个索引,一个简单的索引就像这样:

CREATE INDEX IDX_TRANSACAO_NOVA_STATUS ON TRANSACAO_NOVA(STATUS) TABLESPACE COMVENIF;

这个表有 1000K 寄存器 insinde 和状态表只有 5 或 6 个可能的值。创建索引后,我希望下面的查询会有更好的性能:

select * from transacao_nova tn where tn.status = 'XXX'

但是,解释计划仍然向我展示了一个完整的扫描,成本为 16.000。

有什么帮助吗?我不是 dba,但我需要提高这种性能。

提前致谢。

【问题讨论】:

  • 在某些情况下,优化引擎会决定只进行全表扫描而不是尝试使用索引更便宜。并不是说这里发生了这种情况,但这是发生这种情况的原因之一。
  • 您只需要第一行,还是需要所有行?你建立了统计数据吗?为什么不接受问题的答案?
  • 数据的分布是什么 - 您的行中有多少百分比具有感兴趣的单数状态代码? Oracle 认为数据的分布是什么?
  • 如果您选择 1/6 的表格更改,就像 @MarcB 所说的那样,您所做的就是放慢速度。特别是因为您选择的是 * 而不仅仅是索引列。将提示 /* full(tn) */ 添加到您的选择中,看看需要多长时间。
  • NULL 是可能的值之一吗?

标签: performance oracle indexing


【解决方案1】:

如果只有 5 或 6 个不同的状态值和 100 万条记录,则查询优化器可能会认为不值得使用索引进行范围扫描,但仍会返回表中大量的所有记录。

您可能会考虑为此应用程序使用索引聚集表。

【讨论】:

  • 好点。我错过了大约 5-6 个值的部分。位图索引也可能是一个不错的选择。
【解决方案2】:

如果状态列中的数据出现偏斜(不统一:一些值出现频率很高,而另一些值很少出现),您可以通过刷新统计信息来加速对稀有值的查询(并验证您是否正在为状态列计算直方图。这将使 Oracle 在效率更高的情况下使用索引

http://docs.oracle.com/cd/E11882_01/server.112/e16638/stats.htm#autoId12

请注意,自动确定列是否需要直方图并不是一个好主意,因为它可能会导致不一致的行为。最好在需要时手动指定直方图。此外,直方图会影响使用这些列的每个查询,因此应小心收集它们。

【讨论】:

    【解决方案3】:

    您可能需要在表上生成新的统计信息。

    http://docs.oracle.com/cd/B19306_01/server.102/b14211/stats.htm

    【讨论】:

    • 我运行了静态程序,但性能仍然很差......我会看到关于索引聚集的答案并很快返回。谢谢
    【解决方案4】:

    一个常见的错误是假设索引范围扫描会比完全扫描更好,因为您只需要表中总行数的“一小部分”。但是,如果您想要的行分散在整个表的存储范围内,那么通过索引查找来定位它们可能比仅扫描整个表要慢。我不能肯定你的情况就是这种情况,但有可能。

    要更深入地讨论这个话题,我推荐this paper

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 2017-06-24
      • 1970-01-01
      • 1970-01-01
      • 2016-11-24
      相关资源
      最近更新 更多