##mysql中select查询 in 与 exists 对比
网上有说,将查询中的in 改为exists 可以提高查询速度。接下来咱们就来验证下,他们的速度怎么样。
######0. 首先,两张表 _user,_friend
_user:
column:userid-->primary
count:1000097
_friend:
column:userid-->index
column:friend-->index
count:1140
######1. 先对比下两者的查询速度,很明显,in确实慢很多。
Database changed
mysql> select userid from _user where userid in (select friend from _friend where userid = 100010);
...
27 rows in set (7.52 sec)
mysql> select userid from _user where exists (select friend from _friend where userid = 100010 and _user.userid = _friend.friend);
...
27 rows in set (1.50 sec)
######2. 然后,咋把缓存清空下,先查exists在对比下,这下两者之间的差别就不大了。
mysql> reset query cache;
Query OK, 0 rows affected (0.00 sec)
mysql> select userid from _user where exists (select friend from _friend where userid = 100010 and _user.userid = _friend.friend);
...
27 rows in set (1.49 sec)
mysql> select userid from _user where userid in (select friend from _friend where userid = 100010);
...
27 rows in set (1.58 sec)
######3.重新启动下数据库,在先exists查询试试,这下的速度怎么这么慢的呢。
service mysql restart
Database changed
mysql> select userid from _user where exists (select friend from _friend where userid = 100010 and _user.userid = _friend.friend);
...
27 rows in set (10.82 sec)
mysql> select userid from _user where userid in (select friend from _friend where userid = 100010);
...
27 rows in set (1.59 sec)
######4. explain 简析看看。
mysql> explain select userid from _user where userid in (select friend from _friend where userid = 100010);
+----+--------------------+--------------------+-------+-----------------+-----------------+---------+------------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+--------------------+-------+-----------------+-----------------+---------+------------+--------+--------------------------+
| 1 | PRIMARY | _user | index | NULL | _user_gx | 5 | NULL | 997929 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | _friend | ref | _user_re_userid | _user_re_userid | 18 | const,func | 1 | Using where; Using index |
+----+--------------------+--------------------+-------+-----------------+-----------------+---------+------------+--------+--------------------------+
2 rows in set (0.00 sec)
mysql> explain select userid from _user where exists (select friend from _friend where userid = 100010 and _user.userid = _friend.friend);
+----+--------------------+--------------------+-------+-----------------+-----------------+---------+------------------------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+--------------------+-------+-----------------+-----------------+---------+------------------------+--------+--------------------------+
| 1 | PRIMARY | _user | index | NULL | _user_gx | 5 | NULL | 997929 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | _friend | ref | _user_re_userid | _user_re_userid | 18 | const,fst._user.userid | 1 | Using where; Using index |
+----+--------------------+--------------------+-------+-----------------+-----------------+---------+------------------------+--------+--------------------------+
2 rows in set (0.00 sec)
mysql>
######5.可以看出,两种方式,查询的行都是一样的。两者的效率也是一样的。刚刚看的速度差距只是数据库刚启动,还没有预热造成的误差。