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