场景和环境
- redhat6.5 + 64位 + 12核心 + 16G
- 表数量 600w
- MySQL 5.0
问题描述
在使用in过程中,同事写了一个简单的in条件查询(字段是普通索引,varchar),由于拼装sql的时候,没有使用引号,导致出现大量慢查询
问题SQL
-
select * from member where phone in (1521xxx5541,15845xxx412)
问题SQL和纠正过的写法对比
执行时间
-
mysql> select count(*) total from member_phone where phone in(1521xxx541,15845xxx412);
-
+-------+
-
| total |
-
+-------+
-
| 1 |
-
+-------+
-
1 row in set (2.76 sec)
-
-
mysql> select count(*) total from member_phone where phone in('1521xxx541','15845xxx412');
-
+-------+
-
| total |
-
+-------+
-
| 1 |
-
+-------+
-
1 row in set (0.01 sec)
-
-
mysql> select count(*) total from member_phone where (phone='1521xxx541' or phone='15845xxx412');
-
+-------+
-
| total |
-
+-------+
-
| 1 |
-
+-------+
-
1 row in set (0.00 sec)
EXPLAIN
-
mysql> explain select count(*) total from member_phone where phone in(1521xxx541,15845xxx412) \G;
-
*************************** 1. row ***************************
-
id: 1
-
select_type: SIMPLE
-
table: member_phone
-
type: index
-
possible_keys: phone
-
key: phone
-
key_len: 18
-
ref: NULL
-
rows: 6307075
-
Extra: Using where; Using index
-
1 row in set (0.00 sec)
-
-
mysql> explain select count(*) total from member_phone where phone in('1521xxx541','15845xxx412') \G;
-
*************************** 1. row ***************************
-
id: 1
-
select_type: SIMPLE
-
table: member_phone
-
type: range
-
possible_keys: phone
-
key: phone
-
key_len: 18
-
ref: NULL
-
rows: 2
-
Extra: Using where; Using index
-
1 row in set (0.00 sec)
-
-
mysql> explain select count(*) total from member_phone where (phone='1521xxx541' or phone='15845xxx412') \G;
-
*************************** 1. row ***************************
-
id: 1
-
select_type: SIMPLE
-
table: member_phone
-
type: range
-
possible_keys: phone
-
key: phone
-
key_len: 18
-
ref: NULL
-
rows: 2
-
Extra: Using where; Using index
-
1 row in set (0.01 sec)
总结
在三个类型的sql中,效率从高到低分别是 or,in 添加了引号, in不加引号。在explain中看到不加引号时,显示的用上了索引phone,type 变成了 index ,和全表扫描差不多了,只不过MySQL扫描时按索引的次序进行而不是行。
提醒
在where多个or,in中条件个数比较多,或者多个in 条件时,实际性能都比较差的。以上测试我个人仅在MySQL5.0中测试,高版本官方不知是否优化过。