哪些索引是必要的?

时间:2011-07-29 09:14:32

标签: oracle indexing compound-index

如果我有一个表TABLE_1,请说5列:

COL1    |   COL2    |   COL3    |   COL4    |   COL5
[line]
[line]
[...]

我想要做两个主要的查询:

SELECT * FROM table_a WHERE COL1 = 'X' and COL2 = 'Y'

另一个是:

SELECT * FROM table_a WHERE COL2 = 'Z'

我应该创建哪些索引?使用列COL1COL2创建一个会为两个查询编制索引,还是只需要COL2的另一个索引才能让第二个查询更快?

谢谢!

3 个答案:

答案 0 :(得分:5)

两个查询都可以使用table_a(COL2, COL1)上的常规B树索引。

单独使用COL2索引可能会更有效地仅使用此列上的过滤器来检索行,但附加索引将使用空间并减慢插入速度(如果更新此列,则会更新)。这是一种权衡。

答案 1 :(得分:4)

在他的回答中,文森特说:

  

“table_a(COL2,COL1)上的常规B树索引可以由两者使用   查询“。

该句中的关键词是“可以”。因为任何一个查询都可能不会使用这样的索引。

数据库索引是一个复杂而微妙的主题。有entire books written on the topic。 Richard Foote已成功维持a blog talking about nothing but Oracle Indexes(和David Bowie)

如果不了解关于该表的一些基本事实,我们无法给出问题的明确答案:它有多少行?有多少不同的COL1值?有多少不同的COL2值?

所以,让我们看一些替代答案。

如果TABLEA只包含十几行,则全表扫描的可能性将高于任何索引读取。

如果COL2是唯一的,我们需要的唯一索引是table_a(COL2)

如果COL2是非选择性的(与总行数相比的值相对较少),则第二个查询应该使用全表扫描而不是索引读取。

如果COL2是非选择性的,但COL1具有高度选择性(与行总数相比非常多,但不是唯一的),则第一个查询应使用table_a(COL2, COL1)上的索引。

如果COL2不是特别选择性且COL1不是特别选择性,但两者的组合具有高度选择性,那么第一个查询应使用table_a(COL2, COL1)上的索引。全表扫描将是第二个查询的首选路径。

如果COL1是唯一的,它应该有一个索引,这将在第一个查询中使用,但显然在第二个查询中没有帮助。

然后是NULL的问题,这进一步使问题复杂化。除了复合索引(以及某些其他特殊情况)之外,NULL不会被编入索引。

一个真正完整的答案也将解决偏差的问题:如果COL1中90%的行为'0'而其余的是高度选择性的,那么索引可能有用也可能没用。我们可能需要在收集索引时生成直方图,但是当查询使用文字而不是绑定变量时,它们才真正有用。

答案 2 :(得分:1)

您可以考虑在col2和col1上使用复合索引。有关详细信息,请参阅Oracle concepts guide