优化数据库查询的问题, 使 MySQL 负载降到 1%

继上次Redis 事件之后，最近运维收到广告系统的MySQL告警信息

然后让我排查一下最近代码是不是有什么改动，从而导致数据库负载升高。如图:

很明显的可以看出来，在图中的鼠标所在的时间点，负载瞬间升高，然后一直持续没有降下去.

我赶紧打开Git查看一下当天提交的代码，发现当天并没有代码提交部署，所以可能是运营配置导致的.

打开阿里云的SQL洞察和审计功能 (其它云厂商也有类似的数据库审查服务)

如图，很快就可以定位到这条有问题的SQL, 对比于其它查询占比了90%+

接下来的事情就很简单了，直接找到这条SQL对应的代码，然后分析一下:

之前同事写这段代码时，运营只配置了一个，现在运营允许配置有多个选项

没有使用缓存

随后优化了一下这段代码的查询逻辑，并加上相应的缓存处理

修改完之后，可以看到数据库负载降下去了，但是另外一条SQL的占比变高了，并且由于是使用了where exists 可以看到平均耗时远远大于其它SQL

一样的方式定位到SQL对应的代码

在Laravel中使用了whereHas生成这个where exists, 由于外表的数据集比较多，导致查询比较慢

github 有好几个解决方法, 无非就是where in替代掉where exists

然后按着这个方案自己写了一些代码修复好，也可以使用第三方包来处理

如上图，处理好后的查询语句基本都比较均匀了

并且数据库负载也降低到1%了，同时期的负载在50%左右