本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/60
考虑如下两个sql:
select * from table where id in (xxx,xxx,xxx...,xxx)
select * from table where id=xxx or id=xxx or id=xxx ... or id=xxx
哪个效率更高呢?
首先应该明白的一点是mysql会对in的列表进行排序(升序),然后再进行查询。当id为主键时,两个sql效率差别不大,都运用了主键进行查询。但是当id上没有索引时,mysql会扫描整个表,对每一个元组的id去in的列表或者or的列表里进行查询,看是否在其列表当中。但是由于in的列表是有序的,mysql会运用二分查找,时间复杂度为O(logN),但是or的列表mysql进行逐一查找,时间复杂度为O(N)。所以在没有索引时,in的效率会高于or。
在InnoDB引擎下,in返回的顺序是按照主键排序的,我以前一直以为是按照in列表里排序好的顺序进行排序的:
mysql> show create table aG;
*************************** 1. row ***************************
Table: a
Create Table: CREATE TABLE `a` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`data` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=22 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
ERROR:
No query specified
mysql> select * from a where data in(10,3,0,1,2,8,7,5);
+----+------+
| id | data |
+----+------+
| 1 | 1 |
| 2 | 0 |
| 3 | 3 |
| 5 | 0 |
| 6 | 3 |
| 7 | 0 |
| 8 | 10 |
| 20 | 10 |
+----+------+
8 rows in set (0.00 sec)