最近在编码中,遇到了一个坑。

我们有一张用户表

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的结果显示,这条语句需要走全表扫描。

GoEGKf.jpg

经过分析后,发现原因是因为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

对索引字段做函数操作,优化器会放弃使用索引。

又学到东西了

Last modification:April 10th, 2020 at 08:49 pm
如果觉得我的文章对你有用,请尽情赞赏 🐶