【问题标题】:Declaring indexes together or separately, what is the difference?一起或单独声明索引,有什么区别?
【发布时间】:2012-12-17 00:56:07
【问题描述】:

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

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

而不是单独声明?

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

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

【问题讨论】:

标签: mysql indexing


【解决方案1】:

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

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

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

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

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

有关更多详细信息和示例,请参阅我的演示文稿How to Design Indexes, Really。或在video 上观看我的演示。


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

如果您有两个电话簿,一个按姓氏组织,另一个按名字组织,您可以在姓氏簿中搜索“Smith”,在名字簿中搜索“Sarah”,然后以某种方式找到交集两个结果中。 MySQL 有时会尝试使用 index merge algorithm 来执行此操作。

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

【讨论】:

  • 此答案解决了将事物放入多列索引的顺序,而不是何时使用单列与多列。它应该阐明使用单列索引的任何限制/优势。
  • 为了帮助我的意思,在另一个答案中,暗示多个单列索引可以提供多列索引的大部分好处:stackoverflow.com/a/12222699/457836 在这种情况下,我觉得我可能想要如果我可能还需要单独引用这些列,三个单列索引?
【解决方案2】:

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

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

这在【MySQL 文档】中有详细解释

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    • 2016-02-22
    • 2010-11-27
    • 2015-06-07
    相关资源
    最近更新 更多