【问题标题】:Can MySQL use multiple indexes for a single query?MySQL 可以为单个查询使用多个索引吗?
【发布时间】:2012-08-26 16:50:21
【问题描述】:

想象一个包含多个列的表,例如id, a, b, c, d, e。我通常通过id 选择,但是,客户端应用程序中有多个查询对列的子集使用各种条件。

当 MySQL 在单个表上执行多个列上具有多个 WHERE 条件的查询时,它真的可以利用在不同列上创建的索引吗?或者,使其快速的唯一方法是为所有可能的查询创建多列索引?

【问题讨论】:

  • 您有查询示例吗?
  • @Ekaterina, привет :) 这个问题涵盖了一个吸引实践和经验的一般问题,我相信这里不需要具体的查询。但是,如果有意义的话,我可以想一个例子

标签: mysql indexing database-indexes


【解决方案1】:

是的,MySQL 可以为单个查询使用多个索引。优化器将确定哪些索引将使查询受益。您可以使用EXPLAIN 获取有关 MySQL 如何执行语句的信息。您可以使用如下提示添加或忽略索引:

SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a;

我建议阅读how MySQL uses indexes

摘录几句:

如果在多个索引之间进行选择,MySQL 通常使用 找到最少行数的索引。

如果 col1 和 col2 上存在多列索引,则相应的 可以直接获取行。如果存在单独的单列索引 在 col1 和 col2 上,优化器将尝试使用索引合并 优化(参见第 8.2.1.4 节,“索引合并优化”),或 尝试通过决定哪个索引来找到最严格的索引 找到较少的行并使用该索引来获取行。

【讨论】:

  • 哇,这要么是新东西,要么是我在文档中错过了。谢谢,这很有趣 :) 无论如何,针对特定情况的多列索引应该性能更高。
【解决方案2】:
  • 查询中的每个SELECT——想想UNION、子查询、派生表等——都是单独优化的。也就是说,每个人都可能使用不同的索引。
  • 一个SELECT 可以在所谓的“索引合并”中使用多个索引。这是很少使用的。
  • EXPLAIN 说它正在使用Index merge (intersect) 时,几乎总是可以通过使用包含相交索引使用的列的复合索引来改进它。
  • Index merge (union) 有时(很少)用于OR。这种情况也许可以通过将查询重写为两个SELECTs 中的UNION 来改进。

【讨论】:

    【解决方案3】:

    Mysql 可以使用索引合并来合并两个索引的结果。但这并不是 mysql 的首选方式。如果优化查询执行,它将使用两个索引。但这也是查询开发人员创建复合索引的提示。

    索引合并绝不等同于复合索引。 这是施瓦茨男爵书的摘录 -

    索引合并策略有时效果很好,但更重要的是 通常它实际上是索引不良的表的指示:

    • 当服务器与索引相交时(通常用于 AND 条件),它 通常意味着您需要一个包含所有相关信息的索引 列,而不是必须组合的多个索引。
    • 当服务器联合索引时(通常用于 OR 条件),有时 算法的缓冲、排序和合并操作占用大量 CPU 和内存资源。如果不是所有的 索引是非常有选择性的,所以扫描会返回很多行到 合并操作。

    【讨论】:

      【解决方案4】:

      传统上,MySQL 可以在给定查询中为每个表引用使用一个索引。但是,在更新的 MySQL 版本中,可以执行称为 index merge 的操作,并允许 MySQL 每个表使用多个索引。

      http://openquery.com/blog/mysql-50-index-merge-using-multiple-indexes

      【讨论】:

      • 我认为您应该将其编辑为:"每个表可以使用一个索引reference"
      猜你喜欢
      • 1970-01-01
      • 2011-08-13
      • 2012-06-28
      • 2014-08-10
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多