一、背景
从业务的角度来看:慢SQL会增加RT,导致产品用户体验差,降低用户对产品的好感度。
从数据库的角度来看:慢SQL会影响数据库的性能,每个SQL执行都会消耗一定的资源。假设总资源是100,一条慢SQL占用了30的资源1分钟。那么在这1分钟时间内,其他SQL能够分配的资源总量就是70,如此循环,当资源分配完的时候,所有的新SQL执行就会开始等待。
二、发现
在治理慢SQL前我们需要知道哪些SQL是慢SQL,即明确治理的对象。
2.1、数据库自带的慢sql发现机制
MySQL本身提供了慢查询日志,当SQL耗时超过指定阈值的时候,会将SQL记录到慢查询日志文件中,用户能够从慢查询日志文件中提取出慢SQL。
2.2、应用服务的慢sql发现机制
2.2.1、DruidDataSource
spring.datasource.druid.filters=stat
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=1000
2.2.2、Mybatis Interceptor机制
利用Executor或者StatementHandler,拦截执行情况,相对于DruidDataSource,这个是一条sql的整体执行时间,如果使用了shardingjdbc这种在客户端进行分库分表的技术栈,用DruidDataSource如果有跨表或者跨库查询那么就无法知道sql完整的执行时间。笔者推荐使用StatementHandler,没有获取connection的等待时间,执行时间更精确
三、定位
现在我们发现慢SQL,那么需要将这些慢SQL按不同的服务进行区分并整理一份文档,再定位到对应应用的代码,在文档中记录慢SQL使用在什么业务中,运行在什么场景中(定时任务、在线实时查询等&