mysql 怎么对字段进行判断再执行一条sql_记一次MySQL问题排查

d561ddfe1f45d869850b25e6c25d86cf.png

如果你问程序员害怕什么,那我觉得接手「祖传代码」肯定可以排的上名号,你永远不知道它有哪些神奇的设计,你永远不知道还有哪些彩蛋,也许在下一个转角你就能得到惊喜,最近笔者就遇到了一件让人哭笑不得的事情。

事情是这样的,有一个发券的系统,产品经理准备在这个系统上加新功能,可以给券打上不同的标签,并且前端可以根据不同的标签来筛选我所获得的券,需求不算很复杂,开发,测试都很顺利,然后就上到了pre环境(和线上数据一致,但只有内部流量能访问),可以在测试环境却出了问题,测试同学反馈说接口无法返回数据,我一想这不应该啊,这都测多少遍了怎么还有问题,可以当我自己操作以后,果然接口返回了一个500错误。

出了问题就得排查,当打开日志的时候发现了一个很蹊跷的情况,一些很简单的SQL查询却执行了很长的时间,不信邪我们把日志里的SQL拿到数据库里执行但是发现非常快,几毫秒就返回了,那到底是什么情况呢?

16ba8c093c855e306a2e85d268ce43c0.png
耗时超过2s

绝大部分mysql慢查询的事情其实归根结底都是索引的事情,我们也往索引这个方向查,但是发现表建了索引,explain的结果也表明查询用到了索引,那为什么用到了索引还是这么慢呢,而且还是一个必现的case。

1f367410a5eec38c51e2336ebd27f275.png
用到了索引

然后就和小伙伴一顿查,以为是gorm的问题等等,但都不是,最后在看建表语句的时候发现了一个问题,这个表uid的字段是用varchar类型的,而前端和web应用的uid都是int64类型,导致查询的时候对字段进行了隐式转换然后没有用到了索引,果不其然查询结果也验证了我们设想。

27f8fcc0008229ccc31f54692ba6491d.png
全表扫描

事情到这基本就明了,这个老表建的时候没有考虑后续的情况,对索引字段使用了varchar类型,导致全表扫描耗时过长,此外sql日志对查询字段做了一些处理并不是最后执行的语句,这个地方也误导了我们很久,因为日志里的字段都被引号引起来了,然后手动执行的时候都命中了索引,有的时候「眼见都不一定为实」啊,那为什么测试环境都很正常呢,很简单,因为测试环境数据量少,就算全表扫描也是很快的。MySQL的查询对索引的使用是有条件的,其中一条就是,对索引的任何隐式转换和计算都会导致索引失效,经过了这个case,我想我会对这点记得更久了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值