MySQL 中 where 子句中的多列索引的列顺序是否重要?
Does order of columns of Multi-Column Indexes in where clause in MySQL matter?
我下面有一个table:
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;
我想知道,如果我执行以下两条SQL,它们的性能是否一样?
mysql> select * from student where name='John' and city='NewYork';
mysql> select * from student where city='NewYork' and name='John';
涉及问题:
- 如果有一个多列索引(name,city),两个sql都用吗?
- 优化器是否因为索引将第二个 sql 更改为第一个?
我对其中两个执行explain,结果如下:
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 |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
mysql> 解释 select * 来自学生 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 |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
If, given an index on (name,city)
, I execute the following two SQLs, do they have the same performance?
where name='John' and city='NewYork'
where city='NewYork' and name='John'
是的。
查询规划器不关心 WHERE
子句的顺序。如果您的两个子句都按相等性进行过滤,则计划者可以使用索引。 SQL 是一种声明式 语言,而不是过程式。 也就是说,你说你想要什么,而不是如何获得它。这对许多程序员来说有点违反直觉。
它也可以为 WHERE name LIKE 'Raymo%'
使用 (name,city)
索引,因为 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/ 获取有用信息。
多列索引中列的顺序很重要。
multiple-column indexes 的文档内容如下:
MySQL can use multiple-column indexes for queries that test all the columns in the index, or queries that test just the first column, the first two columns, the first three columns, and so on. If you specify the columns in the right order in the index definition, a single composite index can speed up several kinds of queries on the same table.
这意味着当需要列 name
上的索引时,可以使用列 name
和 city
上的索引,但不能使用它来代替列 [=] 上的索引11=].
WHERE
子句中的条件顺序无关紧要。 MySQL 优化器 does a lot of work 在 WHERE
子句的条件上尽早消除尽可能多的候选行并从表和索引中读取尽可能少的数据(因为一些读取数据被丢弃,因为它与整个 WHERE
子句不匹配)。
我下面有一个table:
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;
我想知道,如果我执行以下两条SQL,它们的性能是否一样?
mysql> select * from student where name='John' and city='NewYork';
mysql> select * from student where city='NewYork' and name='John';
涉及问题:
- 如果有一个多列索引(name,city),两个sql都用吗?
- 优化器是否因为索引将第二个 sql 更改为第一个?
我对其中两个执行explain,结果如下:
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 |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
mysql> 解释 select * 来自学生 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 |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
If, given an index on
(name,city)
, I execute the following two SQLs, do they have the same performance?
where name='John' and city='NewYork'
where city='NewYork' and name='John'
是的。
查询规划器不关心 WHERE
子句的顺序。如果您的两个子句都按相等性进行过滤,则计划者可以使用索引。 SQL 是一种声明式 语言,而不是过程式。 也就是说,你说你想要什么,而不是如何获得它。这对许多程序员来说有点违反直觉。
它也可以为 WHERE name LIKE 'Raymo%'
使用 (name,city)
索引,因为 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/ 获取有用信息。
多列索引中列的顺序很重要。
multiple-column indexes 的文档内容如下:
MySQL can use multiple-column indexes for queries that test all the columns in the index, or queries that test just the first column, the first two columns, the first three columns, and so on. If you specify the columns in the right order in the index definition, a single composite index can speed up several kinds of queries on the same table.
这意味着当需要列 name
上的索引时,可以使用列 name
和 city
上的索引,但不能使用它来代替列 [=] 上的索引11=].
WHERE
子句中的条件顺序无关紧要。 MySQL 优化器 does a lot of work 在 WHERE
子句的条件上尽早消除尽可能多的候选行并从表和索引中读取尽可能少的数据(因为一些读取数据被丢弃,因为它与整个 WHERE
子句不匹配)。