数据库索引:为什么配对

时间:2010-03-25 15:03:15

标签: sql oracle indexing b-tree-index

我有一个包含多个索引的表,其中有几个重复相同的列:

Index 1 columns: X, B, C, D
Index 2 columns: Y, B, C, D
Index 3 columns: Z, B, C, D

我对实践中的索引知识不是很了解,所以我想知道是否有人可以解释为什么X,Y和Z与这些相同的列配对。 B是生效日期。对于特定生效日期,C是该表的半唯一密钥ID B. D是标识该标识符C的记录优先级的序列。

为什么不创建6个索引,每个索引对应一个X,Y,Z,B,C,D?

我想在另一列T中添加一个索引,但在某些情况下我只会查询T,而在其他情况下我也会指定B,C和D列......所以我应该创建一个一个像上面这样的指数,或者我应该为T创建一个,为T(B,C,D)创建一个?

在谷歌搜索索引的全面报道时,我的运气没有预期的那么多。我可以通过任何资源获得解释和大量B树索引的例子吗?

5 个答案:

答案 0 :(得分:7)

带索引的规则是索引可用于过滤构成用于该索引的列的前缀的任何列列表。

换句话说,当我们过滤X和B,或X,B和C,或者只是X或全部四个时,我们可以使用索引1.

但是,我们不能使用索引来过滤“中间”。这是因为索引的工作并不完全不同于为每行连接这些列的值,并对结果进行排序。如果我们知道我们要寻找的东西是什么开始,我们可以找出索引中的位置 - 就像进行二分查找一样。

这就是单个索引不好的原因:如果我们需要过滤B,C,D以及X,Y和Z中的一个,我们需要三个索引; X,Y作为仅仅过滤Y的索引并不好,因为我们正在寻找的值的前缀 - X - 是未知的。

正如Daniel所提到的,覆盖索引是重复B,C和D的可能解释:即使D从未被过滤,也可能是我们需要您在索引中看到的列,以及然后,我们可以只读取索引中的列,而不是仅使用索引来定位行。

答案 1 :(得分:4)

在这些索引中使用B,C和D的一个原因可能是对于经常使用的查询具有covering index。当索引本身包含特定查询的所有必需数据字段时,您将拥有覆盖索引。

覆盖索引可以显着加快数据检索速度,因为只使用索引页而不是数据页来检索数据。

以下是index 1作为覆盖索引的示例查询:

SELECT B, C, D FROM table WHERE X = '10'

答案 2 :(得分:1)

您应该在(T,B,C,D)中创建它。

假设您在表中有两个带索引的字段:A和B.当您在每个列上创建单独的索引,并且具有如下查询:

SELECT * FROM table WHERE A = 10 AND B = 20

会发生什么:

1)DB创建两个中间结果集,一个是行,其中A = 10,另一个是行,其中B = 20.然后必须将这两个结果集合并为一个(并检查重复)行)。

2)DB创建一个结果集,其中A = 10行。然后必须手动遍历此中间结果集中的所有行,并检查每个B = 10的行。

但是,当您知道索引B依赖于索引A,并且您的查询在B之前使用A时,您可以为这两列创建一个索引:(A,B)

这意味着现在DB将首先找到A = 10的所有行,但由于B是同一索引的一部分,因此它可以使用相同的索引信息将结果集过滤为B也为20的行它不必使两个中间结果集+合并它们,或者只使用其中一个索引并对另一个进行手动扫描。

DB可能还有其他方式处理这些情况,这在很大程度上取决于实现。

答案 3 :(得分:1)

表单(X,B,C,D)中的索引可用于优化查询,如:

... WHERE X rel sthg (possibly ORDER BY B, C, D)
... WHERE X = sthg AND B rel sthg (possibly ORDER BY C, D)
... WHERE X = sthf AND B = sthg AND C rel sthg (possibly ORDER BY D)

等。其中rel是任意关系运算符(<,>,=,< =,> =)和sthg是值或表达式。特别是后两个,排序变量不会被“单列索引变体”优化。

OTOH,它无法优化查询

... WHERE B = sthg

因为它从索引的中间开始;在这里,单列索引可以工作。

答案 4 :(得分:0)

对于您可以获得有关Oracle索引(以及任何其他Oracle相关问题)的详细说明和大量示例的资源,您应该访问并标记askTom

相关问题