MySQL 中 where 子句中多列索引的列顺序是否重要?

Ray*_*Hsu 5 mysql sql indexing query-performance

我有下表:

CREATE TABLE `student` ( 
     `name` varchar(30) NOT NULL DEFAULT '',
     `city` varchar(30) NOT NULL DEFAULT '', 
     `age`  int(11) NOT NULL DEFAULT '0',
     PRIMARY KEY (`name`,`city`) 
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

我想知道,如果我执行以下两条SQL,它们的性能是否相同?

mysql> select * from student where name='John' and city='NewYork';
mysql> select * from student where city='NewYork' and name='John';
Run Code Online (Sandbox Code Playgroud)

涉及问题:

  1. 如果有一个多列索引(name, city),那两条SQL都用了吗?
  2. 优化器是否因为索引而将第二个 sql 更改为第一个?

我对他们两个执行解释,结果如下:

mysql> explain select * from student where name='John' and city='NewYork';
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+

| id | select_type | table   | type  | possible_keys | key     | key_len | ref         | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+

|  1 | SIMPLE      | student | const | PRIMARY       | PRIMARY | 184     | const,const |    1 | NULL  |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
Run Code Online (Sandbox Code Playgroud)

mysql> 解释 select * from student where city='NewYork' and name='John';

+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
| id | select_type | table   | type  | possible_keys | key     | key_len | ref         | rows | Extra |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+

|  1 | SIMPLE      | student | const | PRIMARY       | PRIMARY | 184     | const,const |    1 | NULL  |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
Run Code Online (Sandbox Code Playgroud)

O. *_*nes 6

如果给定 上的索引(name,city),我执行以下两条 SQL,它们是否具有相同的性能?

where name='John' and city='NewYork'

where city='NewYork' and name='John'

是的。

查询规划器不关心WHERE子句的顺序。如果您的两个子句都按相等性进行过滤,则规划器可以使用索引。SQL 是一种声明性语言,而不是过程性语言。也就是说,你说你想要什么,而不是如何得到它。对于许多程序员来说,这有点违反直觉。

它还可以使用(name,city)for 索引,WHERE name LIKE 'Raymo%'因为name它位于索引中的第一个。但它不能将该索引用于WHERE city = 'Kalamazoo'

它可以使用索引WHERE city LIKE 'Kalam%' AND name = 'Raymond'。在这种情况下,它使用索引来查找名称值,然后扫描匹配的城市。

如果您有索引, (city,name)也可以将其用于WHERE city = 'Kalamazoo' AND name = 'Raymond'. 如果两个索引都存在,查询规划器将选择一个,可能基于某种基数考虑。

笔记。city相反,如果和上有两个不同的索引name,则查询规划器无法(截至 2017 年中期)使用其中多个索引来满足WHERE city = 'Kalamazoo' AND name = 'Raymond'

http://use-the-index-luke.com/ 获取有用信息。


axi*_*iac 4

多列索引中的列顺序很重要。

多列索引的文档如下:

MySQL 可以使用多列索引来执行测试索引中所有列的查询,或仅测试第一列、前两列、前三列等的查询。如果在索引定义中以正确的顺序指定列,则单个复合索引可以加快对同一表的多种查询的速度。

这意味着列上的索引namecity当需要列上的索引时可以使用它name,但不能使用它来代替列上的索引city

子句中条件的顺序WHERE并不重要。MySQL优化器在子句上的条件上做了很多工作WHERE,以尽早消除尽可能多的候选行,并从表和索引中读取尽可能少的数据(因为读取的一些数据会被丢弃,因为与整个子句不匹配WHERE)。