6

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

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 是此表在特定生效日期 B 的半唯一键 ID。D 是标识此记录对标识符 C 的优先级的序列。

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

我想将索引添加到另一列 T,但在某些情况下,我只会单独查询 T,而在其他情况下,我还将指定 B、C 和 D 列......所以我应该只创建一个索引,如或者我应该为 T 创建一个,为(T、B、C、D)创建一个?

在谷歌搜索全面覆盖索引时,我没有预期的那么幸运。有什么资源可以让我通过解释和大量 B-tree 索引示例获得?

4

5 回答 5

7

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

换句话说,当我们过滤 X 和 B,或 X、B 和 C,或仅 X,或全部四个时,我们可以使用索引 1。

但是,我们不能使用索引来过滤“中间”。这是因为索引的工作方式与为每一行连接这些列的值并排序结果并不完全不同。如果我们知道要查找的内容以什么开头,我们就可以确定要在索引中查找的位置——就像进行二分搜索时一样。

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

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

于 2010-03-25T15:11:11.940 回答
4

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

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

下面是一个示例查询,其中index 1将是一个覆盖索引:

SELECT B, C, D FROM table WHERE X = '10'
于 2010-03-25T15:06:37.363 回答
1

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

假设您在表中有两个带有索引的字段:A 和 B。当您在每一列上创建单独的索引并进行如下查询时:

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

会发生什么:

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

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

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

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

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

于 2010-03-25T15:13:34.713 回答
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

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

于 2010-03-25T15:15:51.883 回答
0

对于可以在其中获得有关 Oracle 索引(以及任何其他 Oracle 相关问题)的完整解释和大量示例的资源,您应该访问并为 askTom 添加书签。

于 2010-03-27T18:30:08.357 回答