mysql新增数据速度

mysql新增数据速度

场景:前台传来大量数据,需要插入到redis和mysql中,同时进行速度缓慢,还容易丢失数据。下面进行模拟测试。

    //写入mysql时间: 4ms
    //写入redis时间: 78055ms

    //直接批量写入mysql
    //写入mysql时间: 4ms

    //单条写入mysql
    //写入mysql时间: 258971ms
    @Test
    public void CreateCollection() {
        long startTime = System.currentTimeMillis();
        ArrayList<Department> departmentList = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            Department department = new Department();
            department.setId(i);
            department.setName("研1发部" + i);
            department.setDescr("开1发产品" + i);
            //单条记录新增插入
            //departmentMapper.insert(department);

            //redis新增
            //redisDao.set(department.getId().toString(), department.getName());
            departmentList.add(department);
        }
        long endTime = System.currentTimeMillis();
        TraverseCollection(departmentList);
        System.out.println("集合生成加redis写入缓存时间: " + (endTime - startTime) + "ms");

    }

    public void TraverseCollection(ArrayList<Department> departmentList) {
        long startTime = System.currentTimeMillis();
        //创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run(){
                //批量新增mysql
                departmentMapper.insertDepartmentList(departmentList);
            }
        });
        long endTime = System.currentTimeMillis();
        System.out.println("集合解析加写入mysql时间: " + (endTime - startTime) + "ms");
    }

数据脚本

 <insert id="insert" parameterType="com.cxy.template.entity.Department">
        insert into department(id,name,descr) values(#{id},#{name},#{descr})
    </insert>


    <insert id="insertDepartmentList" parameterType="java.util.List">
        insert into department(id,name,descr) values
        <foreach collection="departmentList" item="dml" separator=",">
        (#{dml.id},#{dml.name},#{dml.descr})
        </foreach>
    </insert>

连接池配置

#表明使用Druid连接池
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#初始化时建立物理连接的个数。
spring.datasource.druid.initial-size=5
#最大连接池数量
spring.datasource.druid.max-active=20
#最小连接池数量
spring.datasource.druid.min-idle=5
#获取连接时最大等待时间,单位毫秒
spring.datasource.druid.max-wait=3000
#是否缓存preparedStatement,也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
spring.datasource.druid.pool-prepared-statements=false
#要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
spring.datasource.druid.max-open-prepared-statements= -1
#配置检测可以关闭的空闲连接间隔时间
spring.datasource.druid.time-between-eviction-runs-millis=60000
# 配置连接在池中的最小生存时间
spring.datasource.druid.min-evictable-idle-time-millis= 300000
spring.datasource.druid.max-evictable-idle-time-millis= 400000
#监控统计的stat,以及防sql注入的wall
spring.datasource.druid.filters= stat,wall
#Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔
spring.datasource.druid.aop-patterns= com.web.springbootdruid.service.*
#是否启用StatFilter默认值true
spring.datasource.druid.web-stat-filter.enabled= true
#添加过滤规则
spring.datasource.druid.web-stat-filter.url-pattern=/*
#忽略过滤的格式
spring.datasource.druid.web-stat-filter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
#是否启用StatViewServlet默认值true
spring.datasource.druid.stat-view-servlet.enabled= true
#访问路径为/druid时,跳转到StatViewServlet
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
# 是否能够重置数据
spring.datasource.druid.stat-view-servlet.reset-enable=false
# 需要账号密码才能访问控制台,默认为root
spring.datasource.druid.stat-view-servlet.login-username=root
spring.datasource.druid.stat-view-servlet.login-password=root
#IP白名单
spring.datasource.druid.stat-view-servlet.allow=127.0.0.1
#&emsp;IP黑名单(共同存在时,deny优先于allow)
spring.datasource.druid.stat-view-servlet.deny=

原因:存入mysql数据丢失严重问题,批量建立新增连接,导致数据丢失问题。模拟一万条数据并未出现数据丢失问题。

1.针对非实时现实的数据,可以先批量存入mysql再查询出来,放入redis中,进行显示。
2.使用druid连接池,减少反复创建销毁。
3.使用Executors.newCachedThreadPool(),默认一分钟内线程无响应后,进行回收。