我在处理 mysql 中的大量数据集时遇到了问题,我正在探索许多不同的索引方式。如果我一起声明多个索引,谁能告诉我有什么区别
ALTER TABLE `db`.`test` ADD INDEX `someindex` (field1, field2, field3);
而不是单独声明它们?
ALTER TABLE `db`.`test` ADD INDEX `f1` (field1), ADD INDEX `f2` (field2);
为什么要一起或单独声明它们?
我教 MySQL 培训课程,在讨论多列索引时,我使用电话簿的类比。电话簿基本上是姓氏索引,然后是名字。所以排序顺序取决于哪个“列”在前。搜索分为几类:
如果您的电话簿按名字排序,然后按姓氏排序,那么在上述情况#2 和#3 中,电话簿的排序将帮助您,但在情况#1 中没有帮助。
这就解释了查找精确值的情况,但是如果您按值范围查找呢?假设您想查找名字为 John 且姓氏以“S”开头的所有人(Smith、Saunders、Staunton、Sherman 等)。Johns 在每个姓氏中按 J 排序,但如果您想要所有姓氏以 S 开头的所有 Johns,则不会将 Johns 分组在一起。它们又分散了,所以你最终不得不扫描所有姓氏以“S”开头的名字。然而,如果电话簿是按名字然后按姓氏组织的,那么您会发现所有 Johns 在一起,然后在 Johns 中,所有 S 姓氏将组合在一起。
因此,多列索引中的列顺序绝对很重要。一种类型的查询可能需要索引的特定列顺序。如果您有多种类型的查询,您可能需要多个索引来帮助它们,列的顺序不同。
有关更多详细信息和示例,请参阅我的演示文稿如何设计索引,真的。或者观看我的视频演示。
为了阐明何时使用单列索引与多列索引,请考虑您是否使用电话簿通过姓氏和名字的组合来查找人员。例如“莎拉·史密斯”。
如果您有两个电话簿,一个按姓氏组织,另一个按名字组织,您可以在姓氏簿中搜索“Smith”,在名字簿中搜索“Sarah”,然后以某种方式找到两者的交集结果。MySQL 有时会尝试使用索引合并算法来做到这一点。
最好搜索一个索引,如果它同时按姓氏和名字排序,就像真正的电话簿一样。然后搜索找到书的子集“Smiths”,并且在该子集中,它可以有效地搜索“Sarahs”,因为该子集按名字排序。
数据库通常每个查询只能使用一个索引,因此假设所有三列都在您的“where”子句中,您将需要单个复合索引。
但是,复合索引只能从左到右部分使用,因此如果您有另一个查询,例如仅 field1,则仍将使用复合索引。但是,对于在“where”子句中只有 field2 的查询,不能使用该索引,您将需要一个仅在 field2 上的索引,或者一个复合索引,但以 field2 开头。
这在 [MySQL 文档] 中有详细说明