实在很无语呀遇到一个mysql隐式转換问题,问了周边的dba大拿该问题他们居然反问我,你连这个也不知道白白跟他们混了那么长 尼玛,我还真不知道罪过罪过….
问题是這样的,一个字段叫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) = 。当然直接用to_int是显示转换了但是对比出来的效果是一致的。 不管是隐式转换還是显示转换,速度能起来才怪。 因为mysql不支持函数索引。
sql查询的时候字段的类型要保持一致,不然会数据字段的隐式转换继而出現慢查询。 还是那句废话多看mysql的慢查询日志,有你想要的.
大家觉得文章对你有些作用! 如果想赏钱可以用微信扫描下面的二维码,感謝!
另外再次标注博客原地址