视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MySQL中字符串字段,在使用in时,没有加引号时的性能陷阱
2020-11-09 09:12:50 责编:小采
文档


场景和环境

redhat6.5 + 位 + 12核心 + 16G

表数量 600w

MySQL 5.0

问题描述

在使用in过程中,同事写了一个简单的in条件查询(字段是普通索引,varchar),由于拼装sql的时候,没有使用引号,导致出现大量慢查询

问题SQL

select count(*) total from member_phone where phone in(1521xxx541,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中测试,高版本官方不知是否优化过。

下载本文
显示全文
专题