哪些索引是必需的



如果我有一个表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,以便有第二个查询更快?

谢谢!

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

单独在COL2上使用一个索引可能会更有效,但是额外的索引会占用空间,并且会减慢插入(如果要更新该列的话)的速度。这是一种权衡。

文森特在回答中是这样说的:

" table_a(COL2, COL1)上的常规b树索引可以被两者使用查询。"

那句话的关键字是"可能"。因为这样的索引也可能不会被任何一个查询使用。

数据库索引是一个复杂而微妙的问题。有很多关于这个话题的书。理查德·富特(Richard Foote)的博客一直在谈论Oracle索引(和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',其余的是高度选择性的,那么索引可能有用,也可能没用。当我们收集索引时,我们可能需要生成直方图,但是它们只有在查询使用字面量而不是绑定变量时才真正有用。

可以考虑在col2和col1上使用复合索引。有关更多细节,请参阅Oracle概念指南

相关内容

  • 没有找到相关文章

最新更新