本文目录导读:

针对 Druid 监控 SQL 执行性能,这是一个非常经典且实用的话题,Druid 连接池内置了非常强大的监控和统计功能,能够帮你精准定位慢 SQL、分析数据库访问压力以及 排查连接泄露。
以下是如何利用 Druid 监控 SQL 执行性能的完整指南,从开启配置到关键指标解读。
如何开启 Druid 监控功能?
Druid 的监控功能主要依靠 StatFilter(统计过滤器)和 StatViewServlet(监控页面)。
配置方式(Spring Boot / Spring 示例)
方式 A:application.yml 配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
# 1. 配置 StatFilter (核心!)
filter:
stat:
enabled: true
# 慢 SQL 阈值 (毫秒),超过此值会被记录为慢SQL
slow-sql-millis: 3000
# SQL 合并统计 (将相似SQL合并,如IN参数不同)
merge-sql: true
# 2. 开启 Web 监控 (统计请求/URI)
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: /druid/*
# 3. 开启 StatViewServlet (提供监控页面访问)
stat-view-servlet:
enabled: true
# 登录监控页面的用户名和密码
login-username: admin
login-password: admin
# 允许重置数据 (慎用)
reset-enable: false
# 白名单,为空表示允许所有访问
allow: ""
# 黑名单
deny: ""
方式 B:手动配置 Java Bean
@Configuration
public class DruidConfig {
@Bean
public ServletRegistrationBean<StatViewServlet> statViewServlet() {
ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin");
initParams.put("loginPassword", "admin");
initParams.put("allow", "");
initParams.put("resetEnable", "false");
bean.setInitParameters(initParams);
return bean;
}
@Bean
public FilterRegistrationBean<WebStatFilter> webStatFilter() {
FilterRegistrationBean<WebStatFilter> bean = new FilterRegistrationBean<>(new WebStatFilter());
bean.addUrlPatterns("/*");
bean.addInitParameter("exclusions", "/druid/*");
return bean;
}
}
访问监控页面
启动应用后,访问:http://localhost:8080/druid/index.html,输入配置的用户名密码即可看到控制台。
核心监控页面解读(聚焦 SQL 性能)
在 Druid 监控页面的顶部导航栏,重点关注以下几个页面:
数据源 (DataSource) 页面
- 关键指标:
ConnectCount,ActiveCount,PoolingCount,WaitThreadCount。 - 性能关联:
ActiveCount长期高于MaxActive的 80%,或者WaitThreadCount大于 0,说明数据库连接池可能成为瓶颈(SQL 执行慢导致连接被长时间占用)。
SQL 监控 (SQL Monitor) 页面 —— 核心!
这是定位慢 SQL 和性能瓶颈的重中之重,该页面会列出所有执行过的 SQL,并提供以下关键性能字段:
| 字段 | 含义 | 性能诊断价值 |
|---|---|---|
| ExecuteCount | 执行次数 | 高频SQL,重点关注。 |
| RowCount | 总影响行数 / 总返回行数 | 与执行次数结合,看平均扫描行数。 |
| TotalTime | 总执行时间 (毫秒) | 耗时大户:TotalTime / ExecuteCount = 平均耗时。 |
| MaxTimes | 单次最大耗时 | 是否存在 慢 SQL(看是否超过 slow-sql-millis 配置)。 |
| MaxTime | 单次最长耗时 | 与 MaxTimes 对应的时间点。 |
| ErrorCount | 执行错误次数 | 异常 SQL,通常伴随性能问题。 |
| InTransactionCount | 在事务中执行的次数 | 事务内的SQL,锁、回滚等风险高。 |
| ConcurrentMax | 最大并发执行数 | 监控 SQL 是否被多个线程并发执行(死锁或争用风险)。 |
| FetchRowCount | 总 fetch 行数 | 网络传输数据量,过大可能影响 IO。 |
| EffectedRowCount | 总影响行数 (增删改) | 写入量监控。 |
操作技巧:
- 排序:点击
TotalTime或MaxTimes列头进行降序排序,耗时最高的 SQL 会排在最前面。 - 查看慢 SQL:
MaxTimes列数值较大(如 > 1秒)或标红的 SQL,就是需要优化的对象。 - 查看执行详情:点击某条 SQL 的
SQL链接,可以查看:- 最后的执行计划(如果开启了
show-sql或使用特定数据库方言)。 - 参数化SQL(合并后的模拟SQL,方便分析模板)。
- 执行时间分布(如 0-1ms, 1-10ms, 10-100ms, 100-1000ms, >1000ms 的占比)—— 这是判断 SQL 是否偶尔抖动的利器。
- 最后的执行计划(如果开启了
URI 监控 (Web App / URI Monitor) 页面
- 将应用的每个 HTTP 请求路径(URI)与 Druid 监控关联起来。
- 可以看到哪个 API 接口 消耗了最多的数据库连接或执行了最慢的 SQL,这能帮你快速定位慢接口背后的 SQL 根因。
Spring 监控 (Spring Monitor) 页面
- 如果引入了
druid-spring-boot-starter并开启了 Spring 监控,可以看到每个 Bean 方法的调用耗时,进一步定位是 Service 层还是 DAO 层的开销大。
重点关注与性能调优策略
当你拿到 Druid 的监控数据后,可以按以下步骤进行分析和优化:
抓出 “慢 SQL” (核心目标)
- 定位:在 SQL 监控页,根据
MaxTimes排序,找出所有MaxTimes > 3秒(或你设定的阈值)的 SQL。 - 分析:查看该 SQL 的 执行计划(Druid 通常不直接提供执行计划,你需要去数据库执行
EXPLAIN),分析是:- 全表扫描(未命中索引)?
- 大量文件排序(Using filesort)?
- 临时表(Using temporary)?
- 索引使用错误(type 为 ALL 或 index,而非 ref/range)?
- 优化:添加或优化索引,改写 SQL(如避免
SELECT *、减少 JOIN、分页优化等)。
分析 “高负载 SQL” (高频+高总耗时)
- 定位:根据
ExecuteCount * AvgTime(即总耗时)排序。 - 分析:即使单次不慢,但执行次数极多也会导致高负载,排查是否存在循环调用 SQL、未使用缓存、N+1 查询等问题。
- 优化:使用缓存(Redis/本地缓存)、批处理、减少不必要的查询。
检测 “连接池压力”
- 定位:查看数据源页面,
ActiveCount是否接近MaxActive? - 分析:当多个慢 SQL 并发执行时,它们会浪费连接池资源,导致其他请求等待(
WaitThreadCount增加)。 - 优化:优化慢 SQL 是根本;如果连接池太小,可适当调大
MaxActive,但wait_timeout也要合理设置。
检查 “错误 SQL”
- 定位:
ErrorCount大于 0 的 SQL。 - 分析:SQL 执行错误(如超时、死锁、语法错误)往往比慢 SQL 更严重,需要立即修复。
高级用法与常见问题
监控自定义 SQL(非 Mapper 接口)
如果使用 JdbcTemplate 或原生 Connection 执行 SQL,Druid 的监控同样会自动识别。只要数据源是 DruidDataSource 且 StatFilter 开启,所有经由此数据源的 SQL 都会被监控。
如何获取慢 SQL 的原始日志?
除了在 Web 控制台查看,还可以配置 StatFilter 的日志输出,将慢 SQL 记录到业务日志中:
spring:
datasource:
druid:
filter:
stat:
log-slow-sql: true # 将慢 SQL 输出到日志
slow-sql-millis: 3000
这样你就会在应用日志中看到:
[WARN] slow sql 3074 millis. com.example.dao.UserDao.selectList ...
监控数据持久化
默认 Druid 监控数据存在内存中,重启应用后会丢失,如果需要在生产环境长期存储监控历史:
- 方案:配置
spring.datasource.druid.filter.stat.db-to-file或集成 Grafana + Prometheus,通过 Druid 的 Exporter(如druid-exporter)将指标推送到 Prometheus。
安全提示
- 生产环境:务必给
/druid页面设置强密码(login-username,login-password)或限制 IP 白名单(allow配置)。 - 禁用重置:
reset-enable: false,防止他人清空监控数据。 - 排除路径:
web-stat-filter.exclusions要包含/druid/*,避免监控自身被拦截。
Druid 监控 SQL 性能的黄金流程
- 配置并启用地:在
application.yml中配置stat、web-stat-filter、stat-view-servlet。 - 访问监控页:
http://ip:port/druid/index.html。 - 定位性能问题:
- 去 SQL 监控 页 → 按
TotalTime或MaxTimes排序 → 找出慢 SQL / 高频 SQL。 - 去 URI 监控 页 → 定位慢接口。
- 去 SQL 监控 页 → 按
- 分析 SQL:对于慢 SQL,将 SQL 文本复制到数据库客户端执行
EXPLAIN,检查索引、扫描行数、Extra 字段。 - 优化与验证:
- 优化索引 / SQL。
- 观察 Druid 监控数据的变化(执行耗时是否降低)。
- 持续集成:配置
log-slow-sql: true将慢 SQL 输出到日志告警,实现自动化监控。
Druid 提供的这些监控数据,是判断数据库压力、排查系统性能瓶颈最直接的信息来源,用好它,能大幅提升故障定位效率。