记一次数据库的优化
前几天公司应用后台更新版本,晚上发版,测试 到了12点过,测试的差不多没有问题,其他同事都回家了,我和所谓的主管(要好的朋友)不想回去了,就留在的公司过夜。
第二天起来,我戳了一眼,没有问题,结果到了8点多,团队群里就报登录界面显示不了验证码。(登录需要输入验证码)
迅速的就开始进行问题的检查,因为是验证码无法显示,于是就定位到处理登录的工程account,打开日志一看,报的算是线程耗尽的问题。
之前遇到过这个问题(有一次linux上mysql安装的磁盘不对,被推了大量数据后,磁盘满了,导致处理更新的语句变慢,从而导致应用的线程耗尽)
鉴于上次的经验,这次也是定位到数据库,但是肯定不是上次的问题,也进行了重启,发现根本没有鸟用,看不到什么错,无法跟踪。
最后找了公司的DBA,帮忙看下数据库是不是执行很慢,他查看了一下,跟我们说是数据库挤压的很多的SQL待执行,结果就卡住了,从而导致应用的线程耗尽。
DBA给了我们执行慢的SQL,其实也不复杂,就是一个三表连接查询,就查三个字段,结果执行需要6秒以上的时间。
因为公司应用日活1万多,集中在早上,于是一下子就导致应用不可用了。
快速定位到SQL所用的地方,主要是新版本发布后,增加了记录用户的微信小程序的openid信息,倒是无关紧要,于是就注释了,重新部署,测试一下,完美如初。
程序正常运行之后,我着手看了一下SQL,其实查到表,两张表各有50万数据,另外一张表10几条数据,使用了很多不等于判断,,这样的情况下,居然要5秒以上的执行时间
,真实难以相信,使用explain看了一下执行计划,不过之前学了不少SQL优化,倒是现在看执行计划是真的陌生,没常用,,,不过执行计划都还好,第一张表全部查询,
其他感觉没有什么大问题,部分也使用到了索引,也用了where条件。
因为不等操作可能会导致索引失效,于是把不等操纵都改为的等于操作,结果没有鸟用。
看了一下SQL连接的查询结构,发现了左连接查询的字段,其实是没有命中索引的,于是我改了下数据库的索引,把50万条左连接查询的右表上的连接字段
放到的多列索引的头部,结果SQL一执行,一瞬间就会查询出结果(200ms左右吧)。
算是解决了,真的想不到改一个索引,改变会这么大,后面把程序恢复后重新部署,正常运行。
刚来这个公司不久,虽然是大公司,但是数据库是真的烂,设计数据库都不会太考虑合适的数据类型使用,索引也是来就是一大推,也不管名不命中,
人微又嫌烦,实在不想多说什么。
最后贴一个学习SQL优化时,讲师总结的索引优化的口头禅:
全值匹配我最爱,最左前缀要遵守;
带头大哥不能死,中间兄弟不能断;
索引列上少计算,范围之后全失效;
不等控制还有or,索引失效要远离;
VAR引号不可丢,SQL高级也不难;