这是一个我一直都有的问题。
据我所知,指数的顺序很重要。所以像[first_name, last_name]这样的索引和[last_name, first_name]是不一样的,对吧?
如果我只定义第一个索引,这是否意味着它将仅用于
SELECT * FROM table WHERE first_name="john" AND last_name="doe"; 而不是为了
SELECT * FROM table WHERE last_name="doe" AND first_name="john";因为我使用的是ORM,所以我不知道这些列将被调用的顺序。这是否意味着我必须在所有排列上添加索引?如果我有一个2列的索引,这是可行的,但是如果我的索引是3列或4列,会发生什么呢?
发布于 2009-08-09 21:05:44
当查询条件仅适用于索引的部件时,索引顺序很重要。考虑一下:
SELECT * FROM table WHERE first_name="john" AND last_name="doe"SELECT * FROM table WHERE first_name="john"SELECT * FROM table WHERE last_name="doe"如果您的索引是(first_name,last_name)查询1和2将使用它,查询#3将不会使用它。如果您的索引是(last_name,first_name)查询1和3将使用它,查询#2将不会使用它。在WHERE子句中更改条件顺序在这两种情况下都不起作用。
详情请参阅here
更新
在上面不清楚的情况下-只有当查询条件中的列形成索引的最左边的前缀时,MySQL才能使用索引。上面的查询2不能使用(last_name,first_name)索引,因为它只基于first_name,并且first_name不是(last_name,first_name)索引的最左边的前缀。
查询中条件的顺序并不重要;上面的1号查询将能够很好地使用(last_name,first_name)索引,因为它的条件是first_name和last_name,并且它们加在一起形成了(last_name,first_name)索引的最左边的前缀。
发布于 2009-08-09 22:21:22
ChssPly76认为布尔表达式的顺序不必与索引中列的顺序匹配,这一点是正确的。布尔运算符是commutative,并且MySQL优化器足够智能,能够知道在大多数情况下如何将表达式与索引匹配。
我还想补充一点,您应该学习如何使用MySQL的EXPLAIN特性,这样您就可以自己了解优化器将为给定查询选择哪些索引。
发布于 2014-04-06 20:15:53
为什么不扩展一下答案,让所有的东西都一下子变得清晰起来呢?
如果表具有多列索引,优化器可以使用索引最左侧的任何前缀来查找行。例如,如果您在(col1, col2, col3)上有一个包含三列的索引,那么您在(col1)、(col1, col2)和(col1, col2, col3)上就有索引搜索功能。
如果列不构成索引的最左侧前缀,则MySQL不能使用索引。假设您有如下所示的SELECT语句:
SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;如果(col1, col2, col3)上存在索引,则只有前两个查询使用该索引。第三和第四个查询确实涉及索引列,但(col2)和(col2, col3)不是(col1, col2, col3)最左侧的前缀。- MySQL dev
https://stackoverflow.com/questions/1252279
复制相似问题