想象一下有多列的表,比如id, a, b, c, d, e
。我通常选择id
,但是,客户端应用中有多个查询在列的子集上使用各种条件。
当MySQL在多个列上具有多个WHERE条件的单个表上执行查询时,它是否真的可以使用在不同列上创建的索引?或者,使其快速的唯一方法是为所有可能的查询创建多列索引?
答案 0 :(得分:54)
是的,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.3.1.4节“索引合并优化”)或 尝试通过决定哪个索引来找到最严格的索引 找到更少的行并使用该索引来获取行。
答案 1 :(得分:18)
传统上,MySQL可以在给定查询中为每个表引用使用一个索引。但是,在更新版本的MySQL中,可能会发生一个名为index merge
的操作,并允许MySQL为每个表使用多个索引。
http://openquery.com/blog/mysql-50-index-merge-using-multiple-indexes
答案 2 :(得分:1)
SELECT
(例如UNION
,子查询,派生表等)都是分别优化的。那就是每个人可能使用不同的索引。SELECT
可以在所谓的“索引合并”中使用多个索引。这是很少使用的。EXPLAIN
说它正在使用Index merge (intersect)
时,几乎总是可以通过使用包含相交索引所使用的列的复合索引来对其进行改进。Index merge (union)
有时(很少)用于OR
。通过将查询重写为两个UNION
中的SELECTs
,可以可能得到改善。答案 3 :(得分:0)
Mysql可以使用索引合并来合并两个索引的结果。但这并不是mysql的首选方式。如果优化查询执行,它将使用两个索引。但这也为查询开发人员创建复合索引提供了提示。
索引合并绝不等于复合索引。 这是施瓦茨男爵书的摘录-
索引合并策略有时效果很好,但更多 它实际上通常是表索引不足的指示:
•当服务器与索引相交时(通常用于AND条件), 通常意味着您需要一个包含所有相关内容的索引 列,而不是必须组合的多个索引。
•服务器联合索引(通常用于“或”条件)时,有时 算法的缓冲,排序和合并操作占用大量CPU 和内存资源。如果不是所有的 索引具有很高的选择性,因此扫描会将许多行返回给 合并操作。