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

时间:2017-07-14 10:02:59

标签: 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;

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

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

涉及的问题:

  1. 如果有多列索引(名称,城市),那么两个SQL都会使用吗?
  2. 优化器是否因为索引而将第二个sql更改为第一个?
  3. 我对其中两个执行解释,结果如下:

    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 * from student where 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  |
    +----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
    

2 个答案:

答案 0 :(得分:1)

  

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

     

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

     

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

查询计划程序不关心WHERE子句的顺序。如果两个子句都过滤了相等性,则规划器可以使用索引。 SQL是声明性语言,而不是过程。也就是说,你说你想要什么,而不是如何获得它。

它还可以使用(name,city)的{​​{1}}索引,因为WHERE name LIKE 'Raymo%'是索引中的第一个。但是,它不能使用name的索引。

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

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

请注意。如果您在WHERE city = 'Kalamazoo' AND name = 'Raymond'city上有两个不同的索引,则查询规划器不能(截至2017年中)使用多个索引来满足name

http://use-the-index-luke.com/获取好消息。

答案 1 :(得分:1)

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

multiple-column indexes的文档内容为:

  

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

这意味着当需要列name上的索引但是不能使用列city上的索引时,可以使用列namecity上的索引}。

WHERE条款中的条件顺序并不重要。 MySQL优化器does a lot of work关于WHERE子句的条件,尽可能早地消除尽可能多的候选行,并从表和索引中读取尽可能少的数据(因为一些读取)数据被删除,因为它与整个WHERE子句不匹配。