mysql查询前转换为数字_mysql: 隐式类型转换

前些天有个同事说他数据库查询性能很差,对查询的列加了索引还是很慢。我一看他的表结构和代码转换出的查询语句,大概知道是什么问题 — 出现了隐式类型转换。当我们对不同类型的值进行比较时,MySQL 为了让这些不同类型的值可比较,就会对它们进行类型转换。通过 MySQL 文档 我们可以查看有哪些情况会出现类型转换。最常见的情况就是 一个字符类型的列在查询的时候我们传递了一个数字,举个例子,建张表,随便灌几十万数据进去:

CREATE 

比如我们做一个简单的查询:

SELECT * FROM implicit_conv where num_str = 1000002

发现性能确实很差,explain 一下发现建好的索引确实没用上:

8f6edd5994517c9aec40c37899180458.png
SELECT * FROM implicit_conv where num_str = '1000002'

将 1000002 改为字符串 '1000002' 发现性能上来了,explain 一下发现索引用上了:

484b1884139a9c1f49ac267b7dbc7f22.png

隐式类型转换除了会带来性能问题,还可能带来安全问题,也可能对你的业务造成意料之外的结果:比如你插入一条 num_str 为 01000002abc 的数据,你再次查询,结果就不对了:

5f0381245056d48bbde2e83a94605027.png

原因就是和文档中提到的,这个时候发生隐式类型转换,将 1000002 和 num_str 列中的值都转换为浮点类型的进行比较,01000002abc 转换为浮点类型的和 1000002的结果一样,所以都被查询出来了。

如果你插入的值不是 01000002abc 而是 01000002 那就更危险了,你在对 1000002 记录更新或删除时,可能将其它的记录也一并更新或删除了:

cdd3912b539337dd867f227539ae8bea.png

我们这里还有一个对比的例子,就是 str_num 列,这是 int 类型的,这个不管我们是用数字来查询还是用字符串来查询都能使用到索引:

31655fc1b571f3b5aa8d71ba30dc8f9d.png

为什么都用上索引呢?这个难道没发生隐式类型转换吗?当然也发生了,文档里也说了;这里还能使用索引就是因为 int 转换为浮点类型结果是一样的,所以还能用索引。查询没性能问题但是还是一样存储业务问题的,你查询的是 0100050 但 100050 这条结果被查询出来了:

b3f54f0e9b5eeb3101a5715c1c871d13.png

所以我们在日常工作中一定要小心隐式类型转换。避免出现一些“感觉不可思议“ 的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值