MySQL索引和订单

Jul*_*oux 30 mysql indexing sql-order-by

这是我永远的问题.

据我所知,指数的顺序很重要.所以索引就像[first_name, last_name] 是不一样了[last_name, first_name]吧?

如果我只定义第一个索引,它是否意味着它只用于

SELECT * FROM table WHERE first_name="john" AND  last_name="doe"; 
Run Code Online (Sandbox Code Playgroud)

而不是

SELECT * FROM table WHERE  last_name="doe" AND first_name="john";
Run Code Online (Sandbox Code Playgroud)

由于我使用的是ORM,因此我不知道这些列的调用顺序.这是否意味着我必须在所有排列上添加索引?如果我有一个2列索引,这是可行的,但如果我的索引在3或4列上会发生什么?

Chs*_*y76 49

当您的查询条件仅适用于索引的PART时,索引顺序很重要.考虑:

  1. SELECT * FROM table WHERE first_name="john" AND last_name="doe"

  2. SELECT * FROM table WHERE first_name="john"

  3. SELECT * FROM table WHERE last_name="doe"

如果您的索引是(first_name,last_name)查询1和2将使用它,查询#3将不会.如果你的索引是(last_name,first_name)查询1和3将使用它,查询#2将不会.在任何一种情况下,更改WHERE子句中的条件顺序都不起作用.

细节在这里

更新:
如果上述情况不明确 - 如果查询条件中的列形成索引的最左前缀,MySQL只能使用索引.上面的查询#2不能使用(last_name,first_name)索引,因为它仅基于first_name并且first_name不是(last_name,first_name)索引的最左前缀.

查询中的条件顺序无关紧要; 上述查询#1将能够使用(last_name,first_name)指数就好,因为它的条件 first_namelast_name与合在一起,它们DO形成(的最左前缀last_name,first_name)指数.


Bil*_*win 5

ChssPly76是正确的,布尔表达式的顺序不必与索引中的列顺序匹配.布尔运算符是可交换的,并且MySQL优化器足够聪明,知道在大多数情况下如何将表达式与索引匹配.

我还想补充一点,你应该学习如何使用EXPLAINMySQL 的功能,这样你就可以自己查看优化器为给定查询选择哪些索引.