11

我在处理 mysql 中的大量数据集时遇到了问题,我正在探索许多不同的索引方式。如果我一起声明多个索引,谁能告诉我有什么区别

ALTER TABLE `db`.`test` ADD INDEX `someindex` (field1, field2, field3);

而不是单独声明它们?

ALTER TABLE `db`.`test` ADD INDEX `f1` (field1), ADD INDEX `f2` (field2);

为什么要一起或单独声明它们?

4

2 回答 2

12

我教 MySQL 培训课程,在讨论多列索引时,我使用电话簿的类比。电话簿基本上是姓氏索引,然后是名字。所以排序顺序取决于哪个“列”在前。搜索分为几类:

  1. 如果您查找姓氏为 Smith 的人,您可以轻松找到他们,因为这本书是按姓氏排序的。
  2. 如果您查找名字是约翰的人,电话簿没有帮助,因为约翰分散在整本书中。你必须扫描整个电话簿才能找到它们。
  3. 如果您查找具有特定姓氏 Smith 和特定名字 John 的人,这本书会有所帮助,因为您会发现 Smiths 排序在一起,并且在该 Smiths 组中,Johns 也是按排序顺序找到的。

如果您的电话簿按名字排序,然后按姓氏排序,那么在上述情况#2 和#3 中,电话簿的排序将帮助您,但在情况#1 中没有帮助。

这就解释了查找精确值的情况,但是如果您按值范围查找呢?假设您想查找名字为 John 且姓氏以“S”开头的所有人(Smith、Saunders、Staunton、Sherman 等)。Johns 在每个姓氏中按 J 排序,但如果您想要所有姓氏以 S 开头的所有 Johns,则不会将 Johns 分组在一起。它们又分散了,所以你最终不得不扫描所有姓氏以“S”开头的名字。然而,如果电话簿是按名字然后按姓氏组织的,那么您会发现所有 Johns 在一起,然后在 Johns 中,所有 S 姓氏将组合在一起。

因此,多列索引中的列顺序绝对很重要。一种类型的查询可能需要索引的特定列顺序。如果您有多种类型的查询,您可能需要多个索引来帮助它们,列的顺序不同。

有关更多详细信息和示例,请参阅我的演示文稿如何设计索引,真的。或者观看我的视频演示。


为了阐明何时使用单列索引与多列索引,请考虑您是否使用电话簿通过姓氏和名字的组合来查找人员。例如“莎拉·史密斯”。

如果您有两个电话簿,一个按姓氏组织,另一个按名字组织,您可以在姓氏簿中搜索“Smith”,在名字簿中搜索“Sarah”,然后以某种方式找到两者的交集结果。MySQL 有时会尝试使用索引合并算法来做到这一点。

最好搜索一个索引,如果它同时按姓氏和名字排序,就像真正的电话簿一样。然后搜索找到书的子集“Smiths”,并且在该子集中,它可以有效地搜索“Sarahs”,因为该子集按名字排序。

于 2012-12-17T01:55:26.623 回答
2

数据库通常每个查询只能使用一个索引,因此假设所有三列都在您的“where”子句中,您将需要单个复合索引。

但是,复合索引只能从左到右部分使用,因此如果您有另一个查询,例如仅 field1,则仍将使用复合索引。但是,对于在“where”子句中只有 field2 的查询,不能使用该索引,您将需要一个仅在 field2 上的索引,或者一个复合索引,但以 field2 开头。

这在 [MySQL 文档] 中有详细说明

于 2012-12-17T01:13:35.143 回答