我有一张桌子:
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';
涉及的问题:
我对其中两个执行解释,结果如下:
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 |
+----+-------------+---------+-------+---------------+---------+---------+-------------+------+-------+
答案 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
。
答案 1 :(得分:1)
多列索引中列的顺序很重要。
multiple-column indexes的文档内容为:
MySQL可以对测试索引中所有列的查询使用多列索引,或者只测试第一列,前两列,前三列等的查询。如果在索引定义中以正确的顺序指定列,则单个复合索引可以加速同一个表上的多种查询。
这意味着当需要列name
上的索引但是不能使用列city
上的索引时,可以使用列name
和city
上的索引}。
WHERE
条款中的条件顺序并不重要。 MySQL优化器does a lot of work关于WHERE
子句的条件,尽可能早地消除尽可能多的候选行,并从表和索引中读取尽可能少的数据(因为一些读取)数据被删除,因为它与整个WHERE
子句不匹配。