我曾经创建过表上的复合索引(对数学人来说是指标),并且有一个假设它们的工作方式。我只是好奇我的假设是否正确。
我假设当你列出索引的列顺序时,你同时也在指定这些索引将如何分组。例如,如果你有列a
、b
和c
,并按照同样的顺序指定索引a ASC
、b ASC
和c ASC
,那么结果索引将本质上成为每个“组”中a
的多个索引。
这个假设正确吗?如果不正确,结果索引会是什么样子?
我曾经创建过表上的复合索引(对数学人来说是指标),并且有一个假设它们的工作方式。我只是好奇我的假设是否正确。
我假设当你列出索引的列顺序时,你同时也在指定这些索引将如何分组。例如,如果你有列a
、b
和c
,并按照同样的顺序指定索引a ASC
、b ASC
和c ASC
,那么结果索引将本质上成为每个“组”中a
的多个索引。
这个假设正确吗?如果不正确,结果索引会是什么样子?
复合索引的工作方式与常规索引类似,只是它们具有多值键。
如果您在字段(a,b,c)上定义了一个索引,则记录首先按a排序,然后按b排序,最后按c排序。
示例:
| A | B | C |
-------------
| 1 | 2 | 3 |
| 1 | 4 | 2 |
| 1 | 4 | 4 |
| 2 | 3 | 5 |
| 2 | 4 | 4 |
| 2 | 4 | 5 |
复合索引就像字典中的普通字母索引,但它覆盖了两个或更多字母,就像这样:
AA - page 1
AB - page 12
表格行首先按照索引中第一列的顺序排序,然后按照第二列等等。
当您通过两列或第一列进行搜索时,这是有用的。如果您的索引如下所示:
AA - page 1
AB - page 12
…
AZ - page 245
BA - page 246
…
你可以将它用于搜索2
个字母(= 2
列在一个表中),或者像一个单独的字母索引:
A - page 1
B - page 246
…
请注意,对于字典而言,页面本身是按字母顺序排列的。这是聚集索引的一个例子。
在普通的、非聚集索引中,页面的引用是有序的,就像历史书一样:
Gaul, Alesia: pages 12, 56, 78
Gaul, Augustodonum Aeduorum: page 145
…
Gaul, Vellaunodunum: page 24
Egypt, Alexandria: pages 56, 194, 213, 234, 267
当你需要按照两个或更多列进行排序时,复合索引也可以被使用。在这种情况下,DESC
子句可能会很有用。
请参阅我博客中有关在复合索引中使用DESC
子句的文章:
结果索引将是单个索引,但具有复合键。
KeyX = A,B,C,D; KeyY = 1,2,3,4;
索引 KeyX,KeyY 实际上将是:A1,A2,A3,B1,B3,C3,C4,D2
因此,在需要通过 KeyX 和 KeyY 查找内容时,速度会很快,并且使用单个索引。例如 SELECT ... WHERE KeyX = "B" AND KeyY = 3。
但重要的是要理解:WHERE KeyX = ? 请求将使用该索引,而 WHERE KeyY = ? 将不会使用此类索引。
哪些查询可以通过复合索引加速,哪些不能
一般来说,复合索引只能显著加速最后一列的不等式。
例如,一个x-y复合B树索引可以:
x = 1 and y = 2
:两列都相等x = 1 and y > 2
:第一列相等,第二列不等x > 1 and y > 2
:两列都不等,包括第一列x > 1 and y = 2
:第一列不等y > 2
:这相当于x > -无穷大 and y > 2
,所以对于复合B树索引来说,这是最糟糕的情况。然而,这种情况可以通过B树索引高效解决。如果您需要在两列上使用不等式,那么您应该了解一些空间索引,例如R树。我已经提供了更多详细信息,链接在这里:什么是空间索引,何时应该使用它?
例如,考虑以下索引:
x|y
1|1
1|2
1|3
1|4
1|5
1|6
2|2
2|2
2|2
2|3
2|3
2|3
2|4
2|4
2|4
4|2
4|2
4|2
4|3
4|3
4|3
4|4
4|4
4|4
5|3
5|4
5|5
5|6
5|7
5|8
只有当索引中的所有行都是相邻的时,索引才能显著加快查询速度。
所以,例如,如果我们想要:
x = 5 and y > 4
5|5
5|6
5|7
5|8
x > 0 and y > 4
1|5
1|6
5|5
5|6
5|7
5|8