今天遇到一个慢查询,查询日志找到慢查询语句是这样的:html
select * from convert_test where areacode=0001 and period>='20170511' and period<='20170511';
convert_test
表结构以下:mysql
CREATE TABLE `convert_test` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `areacode` char(12) NOT NULL DEFAULT '', `period` int(6) unsigned NOT NULL DEFAULT 0, `mid_price` int(10) unsigned NOT NULL DEFAULT 0, `mid_change` float NOT NULL DEFAULT 0, `updated_datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `idx_areacode_period` (`areacode`,`period`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='隐式转换测试表';
表中数据42W以上。git
乍一看,明明建立了一个惟一索引,正常来讲,上面的查询语句应该正好命中idx_areacode_period这个索引的,不该该是慢查询的。github
为了查看这个语句是怎么查询的,咱们在测试库中explain一下:sql
mysql> explain select * from convert_test where areacode=0001 and period>='20170511' and period<='20170511';
结果以下:测试
能够看到,这里是没有用到索引的。spa
定义表的时候,areacode字段是字符串类型的,查询的时候传入的是0001,这里0001被Mysql当作了整数处理为1,Mysql检测到areacode这个字段的查询类型是整型,就会全表扫描,将全部行的areacode转换成整型,而后在作查询处理。日志
找缘由了,就很好解决了,上面的sql语句修改以下:code
mysql> explain select * from convert_test where areacode='0001' and period>='20170511' and period<='20170511';
结果以下:htm
能够看到彻底命中了idx_areacode_period 这个索引。
上面的period定义的时候是整型,可是查询传入的是字符串类型,那为何会命中索引的呢?
看一下官方的隐试转换说明:
因此,下面的几个sql语句有相同的效果:
select * from convert_test where areacode=0001 and period>='20170511' and period<='20170511'; select * from convert_test where areacode=1 and period>='20170511' and period<='20170511'; select * from convert_test where areacode=0001.0 and period>='20170511' and period<='20170511'; select * from convert_test where areacode=1.0 and period>='20170511' and period<='20170511';
mysql 在查询的时候,会将areacode转换成浮点型进行比较。