这是学习笔记的第 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条件的执行计划是一致的,从效率上来说,都是不错的。
对这种场景小结一下:对于数值类型的兼容性,需要尽可能保持一致,如果要反向转换为字符类型,是不建议的。