我在mysql中遇到大量数据集时出现问题,我正在探索许多不同的索引方法。如果我一起声明几个索引,谁能告诉我有什么不同
ALTER TABLE `db`.`test` ADD INDEX `someindex` (field1, field2, field3);
而不是单独声明它们?
ALTER TABLE `db`.`test` ADD INDEX `f1` (field1), ADD INDEX `f2` (field2);
为什么要一起或单独声明它们?
答案 0 :(得分:9)
我教MySQL培训课程,在讨论多列索引时,我使用类比电话簿。电话簿基本上是姓氏的索引,然后是名字。因此排序顺序取决于哪个“列”是第一个。搜索分为几类:
如果您的电话簿按名字排序,则按姓氏排序,对于上述案例#2和#3,书籍的分类将有助于您,但不是案例#1。
这解释了查找确切值的情况,但如果您按值范围查找会怎么样?假设你想找到所有姓名为John且姓氏以'S'开头的人(Smith,Saunders,Staunton,Sherman等)。约翰斯在每个姓氏中都按J排序,但是如果你想要所有姓氏的所有姓氏都以S开头,则约翰斯不会归为一组。它们再次分散,因此您最终必须扫描姓氏以“S”开头的所有姓名。如果电话簿是按名字和姓氏组织的,你会发现所有的约翰在一起,然后在约翰内,所有的S姓都将组合在一起。
因此,多列索引中列的顺序绝对重要。一种类型的查询可能需要索引的特定列顺序。如果您有多种类型的查询,则可能需要多个索引来帮助它们,列的顺序不同。
有关详细信息和示例,请参阅我的演示文稿How to Design Indexes, Really。或者在video上观看我的演示文稿。
要说明何时使用单列索引与多列索引,请考虑您是否使用电话簿通过姓氏和名字的组合查找某个人。例如“莎拉史密斯。”
如果您有两本电话簿,一份按姓氏排列,另一份按名字排列,您可以搜索姓氏书“史密斯”,并在第一本名册中搜索“莎拉”,然后以某种方式找到十字路口这两个结果。 MySQL有时会尝试使用index merge algorithm。
执行此操作最好搜索一个索引,如果它按姓氏和名字排序,就像真正的电话簿一样。然后搜索找到“Smiths”的书的子集,并且在该子集内,它可以有效地搜索“Sarahs”,因为子集按名字排序。
答案 1 :(得分:1)
数据库通常每个查询只能使用一个索引,因此假设所有三列都在“where”子句中,您可能需要单个复合索引。
但是,复合索引只能部分从左到右使用,所以如果你有另一个查询,比如只是field1,那么仍然会使用复合索引。但是,对于在'where'子句中只有field2的查询,该索引不能使用,并且您需要一个索引,该索引只是在field2上,或者是一个复合索引,但是以field2开头。
[MySQL文档]
中对此进行了详细说明