最近在编码中,遇到了一个坑。
我们有一张用户表
CREATE TABLE shu_users (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`name` char(20) NOT NULL COMMENT '用户名',
`mobile` char(11) NOT NULL COMMENT '手机号码',
PRIMARY KEY (`id`),
UNIQUE KEY `mobile` (`mobile`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'
在执行下面这条sql语句时
select * from shu_users where mobile = 13333333333;
虽然我们的mobile字段上有索引,但是explain的结果显示,这条语句需要走全表扫描。
经过分析后,发现原因是因为mobile的字段类型是char(20),但是输入的参数13333333333是整型,mysql在背后做了类型转换。
转换的规则可以查看下面sql的结果来判断。
select "10" > 9;
如果规则是“将字符串转成数字”,那么就是做数字比较,结果应该是1;
如果规则是“将数字转成字符串”,那么就是做字符串比较,结果应该是0。
select "10" > 9;
输出的结果是1,说明是将字符串转换成了数字
。
优化器在背后将我们上面的sql语句改写成了
explain select * from shu_users where CAST(mobile as signed int) = 13333333333
对索引字段做函数操作,优化器会放弃使用索引。
又学到东西了 。