当前位置: 首页 > article >正文

数据库连接池调优——可视化查询慢SQL利器

数据库连接池调优之 Druid:可视化查询慢 SQL 的利器

文章目录

  • 数据库连接池调优之 Druid:可视化查询慢 SQL 的利器
    • 一、Druid 概述
    • 二、Druid 的核心功能
      • (一)高效的连接池管理
      • (二)强大的监控功能
      • (三)灵活的配置与扩展
    • 三、在可视化查询慢 SQL 方面的具体应用
      • (一)慢 SQL 自动捕获与展示
      • (二)深度分析慢 SQL 详情
      • (三)基于慢 SQL 分析的优化建议与实践
    • 四、实战
      • Druid 连接池引入
      • 测试
    • 五、总结

在当今的软件开发领域,数据库操作的性能优化至关重要,而数据库连接池扮演着关键角色。Druid 作为一款功能强大且备受青睐的数据库连接池组件,在处理诸如可视化查询慢 SQL 等方面展现出了卓越的特性和优势。以下将对 Druid 进行详细的介绍。

一、Druid 概述

Druid 是阿里巴巴开源平台上的一个数据库连接池实现,它为开发人员提供了高效、稳定且功能丰富的数据库连接管理方案。除了基础的连接池功能外,Druid 还具备强大的监控和扩展能力,能够帮助开发人员和运维人员深入了解数据库的使用情况,及时发现并解决潜在的性能问题,尤其是在定位和分析慢 SQL 语句方面表现突出。

二、Druid 的核心功能

(一)高效的连接池管理

  • Druid 采用了先进的连接池算法,能够有效地管理数据库连接的创建、复用和销毁。它可以根据配置的参数,合理地控制连接池中连接的数量,避免过多的连接创建导致数据库资源耗尽,同时也能确保在高并发场景下有足够的可用连接,保障系统的响应速度。例如,在一个电商系统的促销活动期间,大量用户同时访问数据库进行下单、查询商品等操作,Druid 能动态分配和复用连接,使得数据库操作能够顺畅进行。
  • 其内置的连接泄漏检测机制也是一大亮点。如果某个数据库连接长时间未被正确释放,Druid 能够及时检测出来,并通过日志等方式提醒开发人员,有助于快速定位代码中可能存在的资源管理漏洞,防止因连接泄漏而引发的数据库性能下降等问题。

(二)强大的监控功能

  • 实时监控
  • 慢 SQL 统计与分析
  • SQL 执行历史查看

(三)灵活的配置与扩展

  • Druid 的配置非常灵活,开发人员可以根据实际项目的需求,轻松调整连接池的各项参数,如初始连接数、最大连接数、最小空闲连接数、连接超时时间等等。这种灵活性使得它能够适配不同规模、不同业务场景的应用系统,无论是小型的企业内部管理系统还是大型的互联网分布式应用,都能通过合理配置 Druid 来优化数据库连接管理。
  • 同时,Druid 支持丰富的扩展接口,开发人员可以基于这些接口进行自定义的功能扩展,比如添加自定义的监控指标、实现特定的连接过滤逻辑等,进一步增强其在特定业务场景下的适用性。

三、在可视化查询慢 SQL 方面的具体应用

(一)慢 SQL 自动捕获与展示

当应用系统运行过程中,Druid 会实时监控 SQL 的执行情况,一旦发现执行时间超过预设阈值(这个阈值可以根据业务实际情况进行配置)的 SQL 语句,就会将其捕获并记录下来。在监控界面中,这些慢 SQL 会以列表的形式呈现,按照执行时间等关键指标进行排序,方便开发人员优先关注那些对性能影响最大的语句。例如,在一个物流管理系统中,如果查询订单运输轨迹的 SQL 经常因为关联表过多、数据量较大而执行缓慢,Druid 就能准确地捕捉到它,并展示出详细的执行信息供开发人员分析优化。

(二)深度分析慢 SQL 详情

点击具体的慢 SQL 条目后,Druid 会展示出该 SQL 语句的全方位详情。包括其完整的 SQL 文本,开发人员可以直观地查看语句的写法是否合理,是否存在不必要的子查询、关联操作过于复杂等情况。同时,还能看到该 SQL 在不同执行时间点的耗时情况统计图表,通过图表分析其执行时间的波动规律,判断是在特定数据量下才出现慢的情况,还是每次执行都很慢等,进一步辅助确定优化方向。此外,展示涉及的数据库表以及索引使用情况,能帮助开发人员判断是否是因为缺少索引或者索引失效导致了 SQL 执行缓慢。

(三)基于慢 SQL 分析的优化建议与实践

根据 Druid 提供的慢 SQL 相关信息,开发人员可以有针对性地采取优化措施。比如,如果发现某条 SQL 语句因为全表扫描导致执行慢,而对应的查询字段适合添加索引,就可以在数据库中为相关字段创建索引后,再次通过 Druid 监控该 SQL 的执行情况,查看性能是否得到了提升。而且 Druid 持续的监控能力可以帮助验证优化后的效果,确保优化举措确实解决了慢 SQL 问题,提高了系统整体的数据库操作性能。

四、实战

在这里插入图片描述

Druid 连接池引入

可以参考 官方文档 引入(虽然也没什么好参考的)。
1)通过 Maven 引入 Druid,并且排除默认引入的 HikariCP:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.23</version>
</dependency>

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
    <exclusions>
        <!-- 排除默认的 HikariCP -->
        <exclusion>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2)修改 application.yml 文件配置。
由于参数较多,建议直接拷贝以下配置即可,部分参数可以根据注释自行调整:


复制代码spring:
  # 数据源配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mianshiya
    username: root
    password: 123456
    # 指定数据源类型
    type: com.alibaba.druid.pool.DruidDataSource
    # Druid 配置
    druid:
      # 配置初始化大小、最小、最大
      initial-size: 10
      minIdle: 10
      max-active: 10
      # 配置获取连接等待超时的时间(单位:毫秒)
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 2000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 600000
      max-evictable-idle-time-millis: 900000
      # 用来测试连接是否可用的SQL语句,默认值每种数据库都不相同,这是mysql
      validationQuery: select 1
      # 应用向连接池申请连接,并且testOnBorrow为false时,连接池将会判断连接是否处于空闲状态,如果是,则验证这条连接是否可用
      testWhileIdle: true
      # 如果为true,默认是false,应用向连接池申请连接时,连接池会判断这条连接是否是可用的
      testOnBorrow: false
      # 如果为true(默认false),当应用使用完连接,连接池回收连接的时候会判断该连接是否还可用
      testOnReturn: false
      # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle
      poolPreparedStatements: true
      # 要启用PSCache,必须配置大于0,当大于0时, poolPreparedStatements自动触发修改为true,
      # 在Druid中,不会存在Oracle下PSCache占用内存过多的问题,
      # 可以把这个数值配置大一些,比如说100
      maxOpenPreparedStatements: 20
      # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作
      keepAlive: true
      # Spring 监控,利用aop 对指定接口的执行时间,jdbc数进行记录
      aop-patterns: "com.springboot.template.dao.*"
      ########### 启用内置过滤器(第一个 stat 必须,否则监控不到SQL)##########
      filters: stat,wall,log4j2
      # 自己配置监控统计拦截的filter
      filter:
        # 开启druiddatasource的状态监控
        stat:
          enabled: true
          db-type: mysql
          # 开启慢sql监控,超过2s 就认为是慢sql,记录到日志中
          log-slow-sql: true
          slow-sql-millis: 2000
        # 日志监控,使用slf4j 进行日志输出
        slf4j:
          enabled: true
          statement-log-error-enabled: true
          statement-create-after-log-enabled: false
          statement-close-after-log-enabled: false
          result-set-open-after-log-enabled: false
          result-set-close-after-log-enabled: false
      ########## 配置WebStatFilter,用于采集web关联监控的数据 ##########
      web-stat-filter:
        enabled: true                   # 启动 StatFilter
        url-pattern: /* # 过滤所有url
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" # 排除一些不必要的url
        session-stat-enable: true       # 开启session统计功能
        session-stat-max-count: 1000 # session的最大个数,默认100
      ########## 配置StatViewServlet(监控页面),用于展示Druid的统计信息 ##########
      stat-view-servlet:
        enabled: true                   # 启用StatViewServlet
        url-pattern: /druid/* # 访问内置监控页面的路径,内置监控页面的首页是/druid/index.html
        reset-enable: false              # 不允许清空统计数据,重新计算
        login-username: root # 配置监控页面访问密码
        login-password: 123
        allow: 127.0.0.1 # 允许访问的地址,如果allow没有配置或者为空,则允许所有访问
        deny: # 拒绝访问的地址,deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝

3)启动后访问监控面板:http://localhost:8101/api/druid/index.html
输入上述配置中的用户名和密码登录:
在这里插入图片描述

测试

使用 Druid 监控
下面我们测试一下因为数据库连接池不足导致的性能问题,并借此带大家熟悉 Druid 监控的使用。
1)将配置中的连接池大小改为 1,且获取连接等待时间超时为 2s:

druid:
  # 配置初始化大小、最小、最大
  initial-size: 1
  minIdle: 1
  max-active: 1
  # 配置获取连接等待超时的时间(单位:毫秒)
  max-wait: 2000

然后任意执行一次对数据库的批量操作,比如插入 20 条数据,每批 2 条,一共 10 批,会随机报错:在这里插入图片描述
查看 Druid 监控,可以看到最大并发为 1,因为连接池的连接数量只有 1:
在这里插入图片描述
除了 SQL 的监控,还有 URI 的监控,可以看到是哪个接口调用了数据库,执行了多少时间。以后出现线上数据库卡死的问题时,很快就能定位到是哪个接口、哪个 SQL 出现了问题(或者访问频率过高)。
在这里插入图片描述
💡 Druid 的 URI 监控是怎么实现的?
核心实现方法如下:

  1. 通过基于 Servlet 的过滤器 WebStatFilter 来拦截请求,该过滤器会收集关于请求的相关信息,比如请求的 URI、执行时长、请求期间执行的 SQL 语句数等。
  2. 统计 URI 和 SQL 执行情况是怎么关联起来的呢? 每次执行 SQL 时,Druid 会在内部统计该 SQL 的执行情况,而 WebStatFilter 会把 SQL 执行信息与当前的 HTTP 请求 URI 关联起来。
    2)将配置中的连接池大小改为 10,且获取连接等待时间超时为 2s:
druid:
  # 配置初始化大小、最小、最大
  initial-size: 10
  minIdle: 10
  max-active: 10
  # 配置获取连接等待超时的时间(单位:毫秒)
  max-wait: 2000

可以看到,SQL 的并发直接变成了 10:
在这里插入图片描述

URI 接口调用的耗时,直接缩小的 10 倍,符合我们提升了 10 倍并发的优化情况:
在这里插入图片描述

有的时候,即使我们服务器 JVM 的内存和 CPU 占用都非常低,其他的中间件比如 MySQL 和 Redis 的占用也非常低,但系统依然会出现响应慢、卡死的情况。这可能就是因为一些配置错误,所以了解这些知识还是非常有必要的。

五、总结

Druid 作为一款优秀的数据库连接池,凭借其高效的连接池管理、强大的监控功能以及在可视化查询慢 SQL 等方面的出色表现,为开发和运维人员在数据库性能优化工作中提供了有力的工具支持。通过合理地应用 Druid,并充分利用其提供的各类功能,能够更加高效地定位和解决数据库操作中的慢 SQL 问题,提升整个应用系统的性能和稳定性,保障业务的顺畅运行。在越来越注重系统性能和用户体验的今天,Druid 的价值也愈发凸显,值得在各类涉及数据库操作的项目中广泛应用和深入探索。


http://www.kler.cn/a/409833.html

相关文章:

  • VSCode 新建 Python 包/模块 Pylance 无法解析
  • 【linux学习指南】初识Linux进程信号与使用
  • 【ArcGISPro】根据yaml构建原始Pro的conda环境
  • 如何在WPF中嵌入其它程序
  • jupyter notebook的 markdown相关技巧
  • [SUCTF2019]SignIn
  • 1.Excel文本函数的使用
  • 通过map文件了解堆栈分配(STM32、MDK5)--避免堆栈溢出
  • 数学知识1
  • ubity3D基础
  • pytorchDay33
  • 【漏洞复现】CVE-2020-1956
  • 在接口实现时使用自定义对象的方法(非工具类,和单例模式)
  • Java中三种常用布局方式
  • Vue报错:error Mixed spaces and tabs no-mixed-spaces-and-tabs——报错处理
  • 神经网络归一化方法总结
  • 鸿蒙心路旅程:探索与收获之旅 勇攀高峰
  • 【我在CSDN成长】我的五周年创作纪念日
  • 掌握控制流的艺术:Go语言中的if、for和switch语句
  • php 导出excel 一个单元格 多张图片
  • 释放已删除空间资源
  • API设计与开发
  • MATLAB R2024b软件下载安装步骤
  • A047-基于Spring Boot的医疗挂号管理系统的设计与实现
  • java编程开发基础,正则表达式的使用案例Demo
  • 基于微信小程序的小动物救助领养平台