MySQL中需要重视的隐式转换

2019-06-04 16:43:14 浏览数 (1)

这是学习笔记的第 1994 篇文章

在系统集成,对接的过程中,很多时候我们都会忽略数据类型的兼容性,导致在系统运转起来的时候,原本正常的流程会容易堵塞,其中一个潜在的原因就是因为数据隐式转换带来的额外代价,为了模拟这个问题,我们使用如下的方式创建表 test,分别指定列name为varchar和int类型,来对比查看隐式转换带来的性能问题。

初始化语句如下:

create table test(id int primary key,name varchar(20) ,key idx_name(name));

insert into test values(1,'10'),(2,'20');

然后我们使用如下的两条语句进行执行计划的对比测试。

l explain select * from test where id=20;

l explain select * from test where id=’20’;

在name列为字符类型时,得到的执行计划列表如下:

执行计划列

Where条件: name=20

where条件: name='20'

id:

1

1

select_type:

SIMPLE

SIMPLE

partitions:

NULL

NULL

type:

index

ref

possible_keys:

idx_name

idx_name

key:

idx_name

idx_name

key_len:

63

63

ref:

NULL

const

rows:

2

1

filtered:

50

100

Extra:

Using where; Using index

Using index

3 warnings (0.00 sec)

1 warning (0.00 sec)

可以很明显的看到,在name为字符串类型时,如果where条件为name=20,则走执行全索引扫描,查看warning信息会明确提示:

Message: Cannot use range access on index 'idx_name' due to type or collation conversion on field 'name'

而如果name列为int类型,使用同样的数据和方式,执行计划列表如下:

执行计划列

where条件: name=20

where条件: name='20'

id:

1

1

select_type:

SIMPLE

SIMPLE

table:

test

test

partitions:

NULL

NULL

type:

ref

ref

possible_keys:

idx_name

idx_name

key:

idx_name

idx_name

key_len:

5

5

ref:

const

const

rows:

1

1

filtered:

100

100

Extra:

Using index

Using index

1 warning (0.00 sec)

1 warning (0.00 sec)

通过上面的测试可以看到,两种where条件的执行计划是一致的,从效率上来说,都是不错的。

对这种场景小结一下:对于数值类型的兼容性,需要尽可能保持一致,如果要反向转换为字符类型,是不建议的。

0 人点赞