Mysql下的SQL优化——隐式类型转换

前几天同事问了一个问题:在一个只有两个值的字段上加索引,在以这个字段为查询条件的时候是否会走索引。同事说不会,我说会走索引。同事不服,于是我们当场做了一个实验。结果居然没有走索引,满脸尴尬,难道真的是我错了?接下来我们分析下

实验表的情况如下

表结构

FieldTypeNullKey
idint(11)NOPRI
ssssvarchar(20)YES
sextinyint(1)YESMUL
varvarchar(1) YESMUL
aaavarchar(1)YES
cccvarchar(1)YES
eeevarchar(1)YES
dddvarchar(1)YES

总数据量200W

数据分布

var的值数据量
09
12097143

var字段只有两种值:0和1。0有9条,1有200W+条

索引

索引名字段索引类型索引方法
idx_varvarNormalBTREE

查询语句

select * from test_200 where var = 1;

执行计划

select typetabletypepossible keyskeykey lenrefrowsfilteredextra
SIMPLEtest_200ALLidx_var202824610Using where

执行计划中显示没有走索引,而是全表扫描,这是为什么呢?

EXPLAIN EXTENDED 看下:

EXPLAIN EXTENDED select * from test_200 where var = 1;
show warnings;
levelCodemessage
Warning1681‘EXTENDED’ is deprecated and will be removed in a future release.
Warning1739Cannot use ref access on index ‘idx_var’
due to type or collation conversion on field ‘var’
Warning1739Cannot use range access on index ‘idx_var’
due to type or collation conversion on field ‘var’
Note1003/* select#1 */ select test.test_200.id AS id,
test.test_200.ssss AS ssss,
test.test_200.sex AS sex,
test.test_200.var AS var,
test.test_200.aaa AS aaa,
test.test_200.ccc AS ccc,
test.test_200.eee AS eee,
test.test_200.ddd AS ddd from test.test_200
where (test.test_200.var = 1)

看到警告中的提示,我开始有点想法了。
提示中说

Cannot use ref access on index ‘idx_var’ due to type or collation conversion on field ‘var’
Cannot use range access on index ‘idx_var’ due to type or collation conversion on field ‘var’

简单来说就是:本次查询不能走 idx_var 这个索引,因为在var 这个字段上发生了类型转换

var 是varchar类型, where条件中使用的是却是数字型 “where var = 1”。所以mysql为了方便与where条件中的1进行比较,把全表中的var值都转换成了数字型,导致了全表扫描。

好了,接下来验证一下我的想法:

查询语句 :

select * from test_200 where var = '1';

执行计划

select typetabletypepossible keyskeykey lenrefrowsfilteredextra
SIMPLEtest_200refidx_varidx_var6const1014123100

从执行计划可以看出,查询已经走索引了。之前不走索引,并不是因为这个字段只有两种值,而是因为where条件的类型不正确,导致mysql进行了 隐式类型转换


  • 隐式类型转换

什么是mysql的隐式类型转换?

看下官网的描述 隐式类型转换

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值