了解MySQL查询中的多个列索引

Joh*_*ohn 58 mysql indexing

这是查询:

SELECT * FROM table WHERE accountid = 1 ORDER BY logindate DESC LIMIT 1
Run Code Online (Sandbox Code Playgroud)

现在,如果我在字段上添加了包含多个列的索引:

INDEX(accountid,logindate)
Run Code Online (Sandbox Code Playgroud)

MySQL会利用这个多列索引吗?或者它不会使用它,因为一个字段在where子句中而另一个在order语句中?或者只要我按多列索引的顺序使用字段,这无关紧要?

Ker*_*mit 57

好问题.

索引从左到右工作,因此您的WHERE条件将使用索引.在这种情况下,排序也会使用索引(下面的执行计划).

手册:

ORDER BY只要索引的所有未使用部分和所有额外ORDER BY列都是WHERE子句中的常量,即使索引与索引不完全匹配,也可以使用索引.以下查询使用索引来解析ORDER BY部件:

SELECT * FROM t1
WHERE key_part1=constant
ORDER BY key_part2;
Run Code Online (Sandbox Code Playgroud)

如果您有一个列index(accountid),则会使用filesort.因此,您的查询确实从该索引中受益.


两栏索引

create table t1 (
  accountid tinyint,
  logindate date);

create index idx on t1 (accountid, logindate);

insert into t1 values (1, '2012-09-05'), (2, '2012-09-09'), (3, '2012-09-04'), 
    (1, '2012-09-01'), (1, '2012-09-26'), (2, '2012-05-16'), 
    (1, '2012-09-01'), (3, '2012-10-19'), (1, '2012-03-01')
Run Code Online (Sandbox Code Playgroud)

执行计划

ID  SELECT_TYPE  TABLE  TYPE  POSSIBLE_KEYS  KEY  KEY_LEN  REF   ROWS  FILTERED  EXTRA
1   SIMPLE       t1     ref   idx            idx  2        const 5     100       Using where; Using index

单列索引

create table t1 (
  accountid tinyint,
  logindate date);

create index idx on t1 (accountid);

insert into t1 values (1, '2012-09-05'), (2, '2012-09-09'), (3, '2012-09-04'), 
    (1, '2012-09-01'), (1, '2012-09-26'), (2, '2012-05-16'), (1, '2012-09-01'), 
    (3, '2012-10-19'), (1, '2012-03-01')
Run Code Online (Sandbox Code Playgroud)

执行计划

ID  SELECT_TYPE  TABLE  TYPE   POSSIBLE_KEYS  KEY  KEY_LEN  REF   ROWS  FILTERED  EXTRA
1   SIMPLE       t1     range  idx            idx  2              5     100       Using where; Using filesort

  • 有关此行的进一步讨论,请参阅我的[索引指南](http://mysql.rjweb.org/doc.php/index_cookbook_mysql). (7认同)