Druid监控SQL执行性能

wen java案例 3

本文目录导读:

Druid监控SQL执行性能

  1. 如何开启 Druid 监控功能?
  2. 核心监控页面解读(聚焦 SQL 性能)
  3. 重点关注与性能调优策略
  4. 高级用法与常见问题
  5. 总结:Druid 监控 SQL 性能的黄金流程

针对 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 总影响行数 (增删改) 写入量监控。

操作技巧

  • 排序:点击 TotalTimeMaxTimes 列头进行降序排序,耗时最高的 SQL 会排在最前面
  • 查看慢 SQLMaxTimes 列数值较大(如 > 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 性能的黄金流程

  1. 配置并启用地:在 application.yml 中配置 statweb-stat-filterstat-view-servlet
  2. 访问监控页http://ip:port/druid/index.html
  3. 定位性能问题
    • SQL 监控 页 → 按 TotalTimeMaxTimes 排序 → 找出慢 SQL / 高频 SQL。
    • URI 监控 页 → 定位慢接口。
  4. 分析 SQL:对于慢 SQL,将 SQL 文本复制到数据库客户端执行 EXPLAIN,检查索引、扫描行数、Extra 字段。
  5. 优化与验证
    • 优化索引 / SQL。
    • 观察 Druid 监控数据的变化(执行耗时是否降低)。
  6. 持续集成:配置 log-slow-sql: true 将慢 SQL 输出到日志告警,实现自动化监控。

Druid 提供的这些监控数据,是判断数据库压力、排查系统性能瓶颈最直接的信息来源,用好它,能大幅提升故障定位效率。

上一篇MyBatis动态SQL标签用法

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!