mysql使用inner join查询导致慢sql
1、起因
数据库隔三差五连接超时,报java.sql.SQLTransientConnectionException:DatebookHikariCP - Connection is not available, request timed out after 30001ms.的错误,如图所示:
2、排查问题
2.1 检查发生慢查询的sql语句。
这里每个项目部署服务器的不同,排查的方式不一样。如果是个人的项目,可以排查一下使用了大量inner join的sql语句。
我们公司用的是华为的数据库,可以通过以下方式查询。
慢日志查询方法如下,实例管理页面-----点击实例名称----日志管理----慢日志,然后根据时间来筛选。
2.2 找到导致慢sql的sql语句后,就到项目里面查看调用了这个sql的方法,或者查看日志,看是哪个方法调用了很多次导致了慢sql。
2.3 找到是哪个方法后,看能不能优化代码逻辑。
2.4 如果不能优化了,就看看sql语句,使用explain看那张表没加索引,导致sql查询慢了。
使用方法:直接在执行的sql语句前面加上explain+空格,然后执行,就可以了。结果如下图:
可以看到有哪些表没加索引,这里我是已经优化过了的,所以每张表都有了索引。至于添加索引的方法,我这里以navicate为例,如下图:
找到需要建索引的表,右键设计表:
选择需要添加索引的字段,可以选择多个字段,也可以选择一个字段。
索引名字取名方法:index_索引的字段名1_索引的字段名2。
例如:index_title
索引类型选择NORMAL,索引方法选择BTREE。
然后ctrl+s保存即可。
2.5 按照以上步骤操作完成后,可以减少sql语句的查询时间,一定程度上解决了慢sql的问题。
3、总结
这次数据库连接超时的问题,一开始我的方向错了,我没有去排查慢sql的问题,我一直以为是网络问题,所以我一开始是通过增加数据库的连接超时时间来解决,发现无论连接超时时间设置为多长,都会出现连接超时的问题,这个时候我就开始思考问题的根源,首先是根据连接数据库超时的时间去查询日志,看看这段时间都做了什么,之后就排查到了sql语句出现慢sql的问题。