记一次隐式转换引起的sql慢查询

前言:

        实在很无语呀,遇到一个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.


对Golang感兴趣的朋友可以加群: 278517979 !!!
另外如果大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码, 感谢!
另外再次标注博客原地址  xiaorui.cc