【问题标题】:Index over a column with only 5 distinct values - Worth it?索引只有 5 个不同值的列 - 值得吗?
【发布时间】:2010-12-25 04:15:00
【问题描述】:

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

会不会,或者我不应该打扰索引

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

【问题讨论】:

  • 当然,这取决于您的查询。该示例给出了您按一个标准过滤的情况:FREQUENCYID。如果您希望以后有其他条件(可能使用动态查询)并且也将按它们进行过滤,那么索引会更有意义。

标签: oracle indexing


【解决方案1】:

索引将在以下情况下有用:

  • 当您搜索不常见的FREQUENCYID 时。就像,您的 10,000,000 行中只有 10FREQUENCYID = 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
    

    可以通过在ROWID 上连接来自FREQUENCYIDOTHERCOLUMN 的索引值来执行。

【讨论】:

    【解决方案2】:

    用典型的查询测试一下,看看哪种方式更快。

    您可能会发现,平均而言,全表扫描比 Rowid 的索引范围扫描 + 表访问更快 - 在这种情况下,Oracle 做对了。

    另一方面,对于您的大多数查询,可能有一些数据模式最好使用索引 - 在这种情况下,您可能需要添加 INDEX 提示。

    【讨论】:

      【解决方案3】:

      这可能是最简单的方法,而不是猜测而是实际尝试。

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

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

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

      【讨论】:

        【解决方案4】:

        这取决于几件事。

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

        其次,是否有可以在不访问表的情况下使用该索引回答的查询?

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

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

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

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

        【讨论】:

          【解决方案5】:

          如果你提到的尺寸会增加

          最多 5.000.000 行

          我建议创建一个索引。

          【讨论】:

            猜你喜欢
            • 2017-10-11
            • 2013-09-28
            • 2011-01-30
            • 1970-01-01
            • 1970-01-01
            • 2013-02-20
            • 1970-01-01
            • 1970-01-01
            • 2018-11-17
            相关资源
            最近更新 更多