只有5个不同值的列的索引 - 值得吗?

时间:2009-12-10 08:56:39

标签: oracle indexing

我有一个潜在最多5.000.000行的表。此表中的一个列在查询中单独使用,但此列只有5个可能的值,目前我有10.000行,根据解释计划,在该列上使用我的索引是没有意义的。

它会不会,或者我不应该为索引而烦恼

编辑:这是目前的两个解释计划 Without index http://img706.imageshack.us/img706/1903/noindex.pngWith forced index via hints http://img692.imageshack.us/img692/8205/indexp.png 后一个图像我用一个提示强制使用索引。

5 个答案:

答案 0 :(得分:8)

这取决于几件事。

首先,价值观的分配。如果您只有五个不同的值,但其中一个占表中行的99.9999%,那么显然您不希望优化器使用该值的索引,但可能希望它使用它为了其他人。在某些情况下,使用基于函数的索引是值得的,以确保您只索引感兴趣的值而不是仅占用空间的值。

其次,是否可以使用该索引回答查询而无需访问该表?

请注意,重要的不仅仅是要访问的行的百分比,而是需要访问的表的块数。例如,如果平均每个块有一个包含1000个块和30个行的表,并且一个列有30个不同的值(每个值在1000行中存在),那么需要访问的块数才能读取每一行单个值在1000/30 = 34(值得使用索引)和1000(不值得使用索引)之间变化,具体取决于行的分布方式。这是由索引的聚类因子表示的 - 如果它的值接近表中的行数,则索引不太可能被使用,如果它接近于块的数量,那么它更可能是用过的。

另外,您可以查看索引压缩以查看是否可以节省空间。

小心使用位图索引 - 它们对于多个会话同时修改的系统不友好(例如,两个人同时将行插入索引表中)。

如果您希望通过这五个值的谓词来提高查询效率,那么更有效的策略是使用分区,部分原因是查询中的分区修剪,但也因为优化器可用的统计数据有所改进知道只能访问一个分区,并且可以使用分区级统计信息而不是全局统计信息。

答案 1 :(得分:2)

索引在以下情况下非常有用:

  • 搜索不常见的FREQUENCYID时。例如,只有10行的10,000,000FREQUENCYID = 1并且您会搜索它。

  • 如果在查询中不使用除FREQUENCYID之外的其他列。这个查询:

    SELECT  FREQUENCYID, COUNT(*)
    FROM    mytable
    GROUP BY
            FREQUENCYID
    

    将从索引中受益(实际上,最有可能会使用INDEX FAST FULL SCANHASH AGGREGATE

  • 当您的表行很大并且您在查询中使用的所有列都被编入索引时。这样,所有索引都将加入而不是FULL TABLE SCAN。比如说,这个查询:

    SELECT  FREQUENCYID, OTHERCOLUMN
    FROM    mytable
    WHERE   FREQUENCYID = 2
    

    可以通过加入FREQUENCYIDOTHERCOLUMNROWID上的索引中的值来执行。

答案 2 :(得分:1)

如果你提到

那么它的大小会增加
  

最多5.000.000行

我建议创建一个索引。

答案 3 :(得分:1)

可能是最简单的方法,不要猜测,但实际上是尝试。

但在我看来,您正在比较执行计划,以便找到最佳方法。这不可靠。优化程序可能没有适当的信息来选择最佳计划(例如,如果您的值分布不均匀且没有直方图)。在解释计划中查看“成本”也没有意义。

更好的方法是比较逻辑IO。运行SQL * Plus,比如set autotrace traceonly,然后运行您的查询(有和没有索引)并比较“一致获取”数字。越少越好。

关于LIO的重要性:article by Cary Millsap

答案 4 :(得分:0)

使用典型查询进行测试,看看哪种方式更快。<​​/ p>

您可能会发现全表扫描的平均速度比Rowid的索引范围扫描+表访问速度快 - 在这种情况下,甲骨文做得恰到好处。

另一方面,也许存在数据模式,对于大多数查询,最好使用索引 - 在这种情况下,您可能希望添加INDEX提示。