【问题标题】:index with multiple columns - ok when doing query on only one column?具有多列的索引 - 仅对一列进行查询时可以吗?
【发布时间】:2010-12-24 08:07:45
【问题描述】:

如果我有一张桌子

create table sv ( id integer, data text )

还有一个索引:

create index myindex_idx on sv (id,text)

如果我进行查询,这仍然有用吗

select * from sv where id = 10

我问的原因是我正在查看一组没有任何索引的表,并看到选择查询的不同组合。有些只使用一列,而另一些则不止一列。我需要为这两个集合创建索引还是一个全包索引可以? 我正在添加索引以实现比全表扫描更快的查找。

示例(基于 Matt Huggins 的回答):

select * from table where col1 = 10
select * from table where col1 = 10 and col2=12
select * from table where col1 = 10 and col2=12 and col3 = 16

都可以被索引表(co1l1,col2,col3)覆盖,但是

select * from table where col2=12

需要另一个索引吗?

【问题讨论】:

  • 我只是

标签: sql oracle indexing


【解决方案1】:

它应该很有用,因为 (id, text) 上的索引首先按 id 索引,然后分别按文本索引。

  • 如果按id查询,会使用这个索引。
  • 如果您通过 id & text 查询,将使用此索引。
  • 如果按文本查询,则不会使用此索引。

编辑:当我说它“有用”时,我的意思是它在查询速度/优化方面很有用。正如 Sune Rievers 指出的那样,这并不意味着您将获得仅给定 ID 的唯一记录(除非您在表定义中将 ID 指定为唯一)。

【讨论】:

  • 如果您通过text 查询,它可能会被使用——成本估算可能仍然有利于索引跳过扫描、索引扫描或快速全索引扫描。
【解决方案2】:

Oracle 支持多种使用索引的方式,您应该首先了解所有这些方式,因此请在此处快速阅读:http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/optimops.htm#sthref973

如果前导列的基数非常低,您的查询select * from table where col2=12 可以有效地利用索引跳过扫描,如果不是,则可以利用快速全索引扫描。这些对于运行报告可能很好,但是对于 OLTP 查询,您最好创建一个以 col2 作为前导列的索引。

【讨论】:

  • +1 用于提及索引跳过扫描。索引压缩、数据基数、统计,所有这些都一起定义了使用的计划。
【解决方案3】:

我假设id 是主键。向索引添加主键没有意义,因为它始终是唯一的。将独特的东西添加到其他东西上也将是独一无二的。

如果你真的需要,给text添加一个唯一索引,否则只需使用id是表的唯一性。

如果id 不是您的主键,则不能保证您从查询中获得唯一的结果。

关于您在col2 上查找的最后一个示例,我认为您可能需要另一个索引。索引并不是性能问题的万灵药,有时您的数据库设计或查询需要优化,例如重写为存储过程(虽然我不完全确定 Oracle 有它们,但我确定有一个 Oracle等价的)。

【讨论】:

  • 向 PK 索引添加另一列可能是有价值的,如果它允许大量查询仅使用索引并完全避免表访问。
  • 是的,但在向另一个(基键)列添加索引时也会出现这种情况。与单值键 + 另一个索引相比,复合键的性能可能略有提升。
【解决方案4】:

如果您的问题背后的驱动因素是您有一个包含多个列的表,并且这些列的任何组合都可以在查询中使用,那么您应该查看 BITMAP 索引。

看看你的例子:

select * from mytable where col1 = 10 and col2=12 and col3 = 16

您可以创建 3 个位图索引:

create bitmap index ix_mytable_col1 on mytable(col1);
create bitmap index ix_mytable_col2 on mytable(col2);
create bitmap index ix_mytable_col3 on mytable(col3);

这些位图索引的最大好处是可以根据需要组合

因此,以下每个查询都将使用一个或多个索引:

select * from mytable where col1 = 10;

select * from mytable where col2 = 10 and col3 = 16;

select * from mytable where col3 = 16;

因此,位图索引可能是您的一个选择。但是,正如 David Aldridge 指出的那样,根据您的特定数据集, (col1,col2,col3) 上的单个索引可能更可取。一如既往,这取决于。查看您的数据以及针对该数据的可能查询,并确保您的统计数据是最新的。

希望这会有所帮助。

【讨论】:

  • +1 非常有趣。不知道位图数组,但en.wikipedia.org/wiki/Bitmap_index 有一篇关于它们的简短文章。
  • 小心——位图索引不适合并发修改,因此在 OLTP 系统中它们通常是一个糟糕的选择。
  • 是的。 OLTP 很差——在数据仓库中很棒。 “和以往一样,这取决于”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 2010-09-20
  • 1970-01-01
  • 1970-01-01
  • 2017-02-06
  • 2016-06-27
  • 2019-09-17
相关资源
最近更新 更多