数字字符串类型不匹配导致的索引失效
假设有一张user表,其中uid为varchar类型,建有索引。
有以下几个查询sql
1.select * from user where uid = ‘xiaoming’;
此时查询正常,使用索引
2.select * from user where uid = xiaoming;
此时查询失败,sql报错
3.select * from user where uid = ‘12345’;
此时查询正常,使用索引
4.select * from user where uid = 12345;
此时查询正常,不使用索引
第4种之所以可以正常查询,这是因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较,但同时也会使索引失效。
今天出现的问题就与第4种有关。
当我们使用#{}的方式来写sql时
public interface UserMapper {
/**
* 使用String查询
*/
@Select("select * from user where uid = #{uid}")
User selectUser(@Param("uid") String uid);
}
当uid='12345’时,我们使用如上的sql执行时,由于uid为String类型,最终执行的结果为select * from user where uid = ‘12345’;此时为第3种情况
public interface UserMapper {
/**
* 使用Long查询
*/
@Select("select * from user where uid = #{uid}")
User selectUser(@Param("uid") Long uid);
}
而当我们使用Long类型时,由于uid为Long类型,最终执行的结果为select * from user where uid = 12345;此时为第4种情况,索引失效。
常见发生场景
比如有两张表,uid_table和user_table,uid_table的uid字段为bigint,user_table的uid字段为varchar,我们在代码中查询uid_table的uid作为查询user_table的参数时,就很可能使用Long类型作为接收uid_table的uid的数据类型,并同时使用Long进行查询user_table,此时就会出现索引失效