记录一次 Springboot + mysql SQL调优(集成 druid 数据库连接池)

当数据量上去了,就会面临一个很严峻的问题,那就是程序运行速度太慢。就像下图这样:
在这里插入图片描述

这个是在日活用户 2W 多的时候记录的:
在这里插入图片描述

主要的解决手段无非就是新增索引、优化 SQL 语句、适当运用缓存等等等…
下面记录一次对 sql 优化的过程以及思路

一、 第一步集成 druid 数据库连接池用于做 sql 监控

  1. maven 引入:
		<!--mysql-->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql-connector-java.version}</version>
		</dependency>
		<!--druid-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.1.10</version>
		</dependency>
		<!--log4j-->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>
  1. application.properties 配置:
### mysql ###
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver


###  druid  ###
# 数据源类型
spring.datasource.type= com.alibaba.druid.pool.DruidDataSource
# 池启动时创建的连接数量
spring.datasource.initialSize=5
# 池里不会被释放的最多空闲连接数量。设置为0时表示无限制。
spring.datasource.minIdle=5
# 同一时间可以从池分配的最多连接数量。设置为0时表示无限制
spring.datasource.maxActive=20
# 在抛出异常之前,池等待连接被回收的最长时间(当没有可用连接时),单位是毫秒。设置为-1表示无限等待。
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
spring.datasource.minEvictableIdleTimeMillis=300000
# 校验SQL,如果不配validationQuery项,则下面三项配置无用
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
# 合并多个DruidDataSource的监控数据
spring.datasource.useGlobalDataSourceStat=true
  1. Druid 配置类:
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class DruidConfig {

    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DruidDataSource druidDataSource(){
       return new DruidDataSource();
    }

    @Bean
    public ServletRegistrationBean druidServlet() {
        DruidDataSource dataSource = druidDataSource();
        ServletRegistrationBean reg = new ServletRegistrationBean();
        reg.setServlet(new StatViewServlet());
        reg.addUrlMappings(new String[]{"/druid/*"});
        // 使用数据库登录用户名密码登录
        reg.addInitParameter("loginUsername", dataSource.getUsername());
        reg.addInitParameter("loginPassword", dataSource.getPassword());
        return reg;
    }

    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns(new String[]{"/*"});
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        filterRegistrationBean.addInitParameter("profileEnable", "true");
        return filterRegistrationBean;
    }
   
}

项目启动后访问 http://localhost:8080/druid 进入监控登录界面如下图所示

在这里插入图片描述

二、 优化思路一:根据最慢 sql 排序,优化慢 sql

一般慢 sql 都是 select , 可以为 where 下的关键字段加上索引,需注意索引的生效规则调整 sql 语句
如果数据量太大或者多表关联统计查询,索引怕是也没有什么用武之地,下图中红色部分是是打算把数据存入 elasticsearch 中再进行查询统计。

在这里插入图片描述

三、 优化思路二:根据 sql 执行数排序,优化频繁重复调用的 sql

在业务代码中经常会有需要某一个数据的时候,比如我的停车场云平台每当有记录上报的时候我都需要获取数据对应的车场,所以根据车场编号查询车场信息这个sql 就会被我频繁的调用。
所以呢我就把查到的车场信息放到缓存中去(我是放在本地缓存,也可以放到 redis 中去,前提是数据量有限哈…),每次查之前先去查缓存数据,查不到再去读库,这样可以大大减少数据库的压力。
ps:当然这样做需要在车场数据更新的时候同时更新去缓存哈…

在这里插入图片描述

优化完之后效果还是很明显的 ヽ(✿゚▽゚)ノ:
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 博客管理系统 ### #Springboot ## 主要功能 * 系统用户,角色,权限增删改查,权限分配,权限配色 * 文件上传可自由选择本地存储,七牛云存储,阿里云存储 * 系统字典 * 配置网站基本信息,包括博客数据限制 * 查看系统关键操作的日志(可在系统后台自动定制需要监控的模板) * 在线新增数据库并直接生成 前,后台基本源码,放到源码相应目录中重启tomcat可直接使用,预览 * 系统定时任务的新增改查 立即启动 暂停 恢复 ## 技术框架 * 核心框架:`SpringBoot` * 安全框架:`Apache Shiro 1.3.2` * 缓存框架:`Redis 4.0` * 搜索框架:`Lucene 7.1` * 任务调度:`quartz 2.3` * 持久层框架:`MyBatis 3` mybatisplus 2.1.4 * 数据库连接池:`Alibaba Druid 1.0.2` * 日志管理:`SLF4J 1.7`、`Log4j` * 前端框架:`layui` * 后台模板:layuicms 2.0。 * 富文本:wangEditor ### 开发环境 建议开发者使用以下环境,这样避免版本带来的问题 * IDE:`eclipse`/`idea` * DB:`Mysql5.7` `Redis` * JDK:`JAVA 8` * WEB:Tomcat8 (采用springboot框架开发时,并没有用到额外的tomcat 用的框架自带的) # 运行环境 * WEB服务器:`Weblogic`、`Tomcat`、`WebSphere`、`JBoss`、`Jetty` 等 * 数据库服务器:`Mysql5.5+` * 操作系统:`Windows`、`Linux` (Linux 大小写特别敏感 特别要注意,还有Linux上没有微软雅黑字体,需要安装这个字体,用于生成验证码) #用户名:admin 密码:123456 #数据库文件:mysiteforme.sql #数据库配置文件:mysiteforme下的src/main/resources下的application.yml #启动文件:mysiteforme下的com.mysiteforme.admin下的MysiteformeApplication.java #注意:启动之前先启动redis # http://localhost:8080 管理员用户名:test 密码:1
SpringBoot中,可以通过在`application.properties`或`application.yml`文件中配置`druid`数据源的主数据库连接信息。具体步骤如下: 1. 在`application.properties`或`application.yml`文件中添加以下配置信息: ```properties # 数据源配置 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false spring.datasource.username=root spring.datasource.password=root # Druid连接池配置 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.druid.initial-size=5 spring.datasource.druid.min-idle=5 spring.datasource.druid.max-active=20 spring.datasource.druid.max-wait=60000 spring.datasource.druid.time-between-eviction-runs-millis=60000 spring.datasource.druid.min-evictable-idle-time-millis=300000 spring.datasource.druid.validation-query=SELECT 1 FROM DUAL spring.datasource.druid.test-while-idle=true spring.datasource.druid.test-on-borrow=false spring.datasource.druid.test-on-return=false spring.datasource.druid.pool-prepared-statements=true spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20 spring.datasource.druid.filters=stat,wall,log4j spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 ``` 2. 在Java代码中通过`@Value`注解获取主数据库连接信息: ```java import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class DataSourceConfig { @Value("${spring.datasource.url}") private String url; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; // getter and setter } ``` 3. 在需要使用主数据库连接信息的地方引用`DataSourceConfig`类并获取连接信息: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MyService { @Autowired private DataSourceConfig dataSourceConfig; public void doSomething() { String url = dataSourceConfig.getUrl(); String username = dataSourceConfig.getUsername(); String password = dataSourceConfig.getPassword(); // ... } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值