MySQL中需要重视的隐式转换

作者: admin 分类: 公众号存档            1 次浏览 发布时间: 2019-05-29 23:38

公众号:杨建荣的学习笔记 · 作者:杨建荣 · 发布:2019-05-29 23:38:07 · 原文链接

这是学习笔记的第 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条件的执行计划是一致的,从效率上来说,都是不错的。

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

admin

杨建荣,《Oracle DBA工作笔记》《MySQL DBA工作笔记》作者,dbaplus社群发起人之一,腾讯云TVP,现任竞技世界系统部经理,拥有十多年数据库开发和运维经验,目前专注于开源技术、运维自动化和性能调优

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注