想象一个具有多列的表,例如id, a, b, c, d, e
. 我通常选择 by id
,但是,客户端应用程序中有多个查询,它们对列的子集使用各种条件。
当 MySQL 对单个表执行多个列上的多个 WHERE 条件的查询时,它真的可以利用在不同列上创建的索引吗?或者让它快速的唯一方法是为所有可能的查询创建多列索引?
想象一个具有多列的表,例如id, a, b, c, d, e
. 我通常选择 by id
,但是,客户端应用程序中有多个查询,它们对列的子集使用各种条件。
当 MySQL 对单个表执行多个列上的多个 WHERE 条件的查询时,它真的可以利用在不同列上创建的索引吗?或者让它快速的唯一方法是为所有可能的查询创建多列索引?
是的,MySQL 可以为单个查询使用多个索引。优化器将确定哪些索引将使查询受益。您可以使用EXPLAIN
来获取有关 MySQL 如何执行语句的信息。您可以使用如下提示添加或忽略索引:
SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a;
我建议阅读MySQL 如何使用索引。
仅摘录几句:
如果在多个索引之间进行选择,MySQL 通常使用找到最少行数的索引。
如果 col1 和 col2 上存在多列索引,则可以直接获取相应的行。如果 col1 和 col2 上存在单独的单列索引,优化器将尝试使用索引合并优化(请参阅第 8.2.1.4 节,“索引合并优化”),或者通过确定哪个索引找到更少的索引来尝试找到最严格的索引行并使用该索引来获取行。
传统上,MySQL 可以在给定查询中为每个表引用使用一个索引。然而,在最新版本的 MySQL 中,可以进行一种称为 an 的操作,index merge
并允许 MySQL 对每个表使用多个索引。
http://openquery.com/blog/mysql-50-index-merge-using-multiple-indexes
Mysql可以使用索引合并来合并两个索引的结果。但这并不是 mysql 的首选方式。如果优化查询执行,它将使用两个索引。但这也是查询开发人员创建复合索引的提示。
索引合并绝不等同于复合索引。这是施瓦茨男爵书的摘录-
索引合并策略有时效果很好,但更常见的是它实际上表明索引不佳的表:
• 当服务器与索引相交时(通常用于 AND 条件),这通常意味着您需要一个包含所有相关列的索引,而不是必须组合的多个索引。
• 当服务器联合索引(通常用于 OR 条件)时,有时算法的缓冲、排序和合并操作会占用大量 CPU 和内存资源。如果不是所有索引都非常有选择性,则尤其如此,因此扫描会将大量行返回给合并操作。
SELECT
in a query -- think UNION
, subquery, derived table, etc -- is optimized separately. That is each might use different indexes.SELECT
can use multiple indexes in what it calls "index merge". This is rarely used.EXPLAIN
says it is using Index merge (intersect)
, then it can almost always be improved by using a composite index containing the columns used by the intersected indexes.Index merge (union)
is sometimes (rarely) used for an OR
. Such can perhaps be improved by rewriting the query to be the UNION
of two SELECTs
.