前言:

        实在很无语呀,遇到一个mysql隐式转换问题,问了周边的dba大拿该问题,他们居然反问我,你连这个也不知道?白白跟他们混了那么长   尼玛,我还真不知道。罪过罪过….  


       该文章后续仍在不断的更新修改中, 请移步到原文地址  http://xiaorui.cc/?p=5147     


       问题是这样的,一个字段叫task_id, 本身是varchar字符串类型,但是因为老系统时间太长了,我以为是int或者bigint,所以直接在代码写sql跑数据,结果等了好久就是没有反应,感觉要坏事呀。在mysql processlist里看到了该sql语句,直接kill掉。 该字段是有索引的,并且他的sql选择性很高,索引的价值也高。 但为什么这么慢? 


分析问题

        通过explain分析出了结果,当使用整型来查询字符串的字段会出现无法走索引的情况,看下面可以知道,key为NULL,没走索引,Rows是很大的数值,基本是全表扫描了。  当正常的用字符串查询字符串就很正常了,索引没问题,rows的值为1,这里说的是扫描聚簇索引的rows,而不是索引二级索引。

那么为什么会出现这问题?

下面是mysql官方给出的说法, 最后一条很重要,当在其他情况下,两个参数都会统一成 float 来比较。 居然新版的mysql在优化器层面已经做了一些调整规避这问题,但我自己的测试版本是mysql 5.6,阿里云用的也是5.7,都没有解决该问题。 看来是更高版本解决吧,这个待验证。 


看完了官方解说,我们知道上面那一句慢查询sql,其实就相当于 where to_int(taskid) = 516006380 。当然直接用to_int是显示转换了,但是对比出来的效果是一致的。  不管是隐式转换,还是显示转换,速度能起来才怪。。。 因为mysql不支持函数索引。

总结

sql查询的时候,字段的类型要保持一致,不然会数据字段的隐式转换,继而出现慢查询。 还是那句废话,多看mysql的慢查询日志,有你想要的.

END.



对Python及运维开发感兴趣的朋友可以加QQ群 : 478476595 !!!
{ 2000人qq大群内有各厂大牛,常组织线上分享及沙龙,对高性能及分布式场景感兴趣同学欢迎加入该QQ群 }

另外如果大家觉得文章对你有些作用!   帮忙点击广告. 一来能刺激我写博客的欲望,二来好维护云主机的费用.
如果想赏钱,可以用微信扫描下面的二维码. 另外再次标注博客原地址  xiaorui.cc  ……   感谢!
暂无相关产品

评论已关闭。