MySQL类型转换引发索引失效(隐式类型转换)
最近在网上看到一篇MySQL字段类型转换引发的索引失效,加上常用编程语言是PHP,需要具体测试一下发生的原因。
准备
CREATE TABLE `brand` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`order` smallint(6) unsigned NOT NULL DEFAULT '0',
`pettype` char(3) CHARACTER NOT NULL DEFAULT '0' COMMENT '品牌类型,1=》狗狗,2=》猫咪',
PRIMARY KEY (`id`),
KEY `order_idx` (`order`) USING BTREE,
KEY `pettype_idx` (`pettype`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
测试
使用order与pettype两个字段来做测试
-
order字段的使用int查询explain SELECT `order` FROM brand where `order` = 1111;id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE brand ref order_idx order_idx 2 const 2 100 Using index -
order字段的使用string查询explain SELECT `order` FROM brand where `order` = '1111';id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE brand ref order_idx order_idx 2 const 2 100 Using index -
pettype字段的使用int查询explain SELECT pettype FROM brand where pettype = 2;id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE brand ALL pettype_idx 1683 10 Using where; Using index -
pettype字段的使用string查询explain SELECT pettype FROM brand where pettype = '2';id select_type table partitions type possible_keys key key_len ref rows filtered Extra 1 SIMPLE brand ref pettype_idx pettype_idx 9 const 38 100 Using index
结论
由以上测试可以看出,当MySQL字段为smallint类型时,不管查询条件是int或者string都能使用order_idx索引。而当字段为char类型时,查询条件为string时,使用了pettype_idx索引;查询条件为int时,使用了全表扫描。
并不是所有隐式类型转换都会造成索引失效
在设计数据字段时应该注意,是否需要string的字段类型;SQL编写时,条件类型是否对应字段类型。避开int条件查string字段的情况。
来源:oschina
链接:https://my.oschina.net/lengan/blog/3212569
