代码之家  ›  专栏  ›  技术社区  ›  svrist

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

  •  7
  • svrist  · 技术社区  · 16 年前

    我有一张最多可以容纳5000.000行的桌子。此表中的一列单独用于查询,但此列只有5个可能值,目前我有10000行,根据“解释计划”,在该列上使用索引毫无意义。

    它会不会,或者我不应该麻烦索引

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

    5 回复  |  直到 16 年前
        1
  •  7
  •   David Aldridge    16 年前

    这取决于几个方面。

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

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

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

    此外,您还可以查看索引压缩,看看它是否节省了您的空间。

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

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

        2
  •  2
  •   Quassnoi    16 年前

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

    • 当你搜索不经常 FREQUENCYID 我们只喜欢 10 你的 10,000,000 行有 FREQUENCYID = 1 然后你搜索它。

    • 当您不使用除 频率标识 在您的查询中。此查询:

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

      将从指数中获益(实际上, INDEX FAST FULL SCAN 随着 HASH AGGREGATE 最有可能使用)

    • 当表行较大并且查询中使用的所有列都被索引时。这样,所有索引都将被联接,而不是 FULL TABLE SCAN . 比如,这个问题:

      SELECT  FREQUENCYID, OTHERCOLUMN
      FROM    mytable
      WHERE   FREQUENCYID = 2
      

      可以通过连接上的索引中的值来执行 频率标识 OTHERCOLUMN ROWID .

        3
  •  1
  •   Adriaan Stander    16 年前

    如果像你所说的那样尺寸会增加的话

    最多5000.000行

    我建议创建一个索引。

        4
  •  1
  •   Egor Rogov    16 年前

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

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

    更好的方法是比较逻辑IO。运行sql*plus,比如 set autotrace traceonly ,然后运行您的查询(有索引和无索引),并比较“consistent gets”编号。越少越好。

    关于狮子座的重要性: article by Cary Millsap .

        5
  •  0
  •   Jeffrey Kemp    16 年前

    用典型的查询测试它,看看哪种方法更快。

    您可能会发现,全表扫描平均比索引范围扫描+按rowid访问表更快,在这种情况下,Oracle做得对。

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