欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mysql隐式转换

程序员文章站 2022-05-11 09:54:16
create table testSql(id int(11),name varchar(11),descid varchar(11));alter table testSql add index(descid) alter table testSql addunique(id) insert into testSqlvalues(1,‘123’,‘1’),(2,‘123a’,‘2’),(3,‘639’,‘3’) select * fromtestSql;tablename: testSql ....

create table testSql(id int(11),name varchar(11),descid varchar(11));
alter table testSql add index(descid) alter table testSql add
unique(id) insert into testSql
values(1,‘123’,‘1’),(2,‘123a’,‘2’),(3,‘639’,‘3’) select * from
testSql;

tablename: testSql fieldName:id,name,descid

什么是隐式转换

在mysql查询中,当查询条件左右两侧的类型不匹配就会发生隐式转换;常见的比如 varchar 转化为 int 如下面的查询

select * from testSql  where name = 123

实际运行的时候,会把上面的 sql语句转化为:

select * from testSql  where cast(name as signed int) = 123

隐式转换可能引发的问题,缺点

如果隐式转换在索引列,那么该索引失效,效率大大降低!

示列:

explain select * from testSql where descid = 1

mysql隐式转换

explain select * from testSql where descid = '1'

mysql隐式转换

分析第一行,sql 没有走索引:因为查询条件左右两边的数据类型不匹配 descid 发生了 隐式转换 。使用了cast函数进行转换,一旦对索引字段使用函数操作,mysql将放弃使用索引。

但是当对主键使用上述操作时:

explain select * from testSql where id = 1
explain select * from testSql where id = '1'

mysql隐式转换

是都会走索引查询的,这是为什么呢?
因为 int 类型的数字只有1能转化为’1’,是唯一确定的。所以虽然需要隐式转换,但不影响使用索引

常见的隐式转换

1, 两个参数至少有一个是 NULL 时,比较的结果也是 NULL,例外是使用 <=>
对两个 NULL 做比较时会返回 1,这两种情况都不需要做类型转换

2, 两个参数都是字符串,会按照字符串来比较,不做类型转换

3, 两个参数都是整数,按照整数来比较,不做类型转换

4, 十六进制的值和非数字做比较时,会被当做二进制串

5, 有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为 timestamp

6, 有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数会将整数转换为 decimal 后进行比较,
如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较

7, 所有其他情况下,两个参数都会被转换为浮点数再进行比较

隐式转换的坑

其实我预期效果应该是 第一条,但是第二条也显示出来了。我们在update delete 处理的时候 ,可能会发现自己不小心 有多删一条,或者多修改一条 可以检查一下是否是上述的原因
mysql隐式转换

总结

  1. 写完sql 记得 explain 看一下执行计划是否走索引
  2. 查询条件两边的类型要一致;发生类型转化可能会造成误操作

如何看懂explain:
https://blog.csdn.net/hollis_chuang/article/details/106368688
参考文章为:
https://mp.weixin.qq.com/s/5HMyBGrOMUXytmPAhgwAgQ

本文地址:https://blog.csdn.net/lin2535290272/article/details/107641818

相关标签: mysql