IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> springboot一次性定时任务插入1000万条数据 -> 正文阅读

[Java知识库]springboot一次性定时任务插入1000万条数据

作者:https://img-blog.csdnimg.cn/img_convert/7b3290e663eec0a8b5b7af48d9dfb892.png

模拟 1000 万个用户,再去查询

导入数据

  1. 用可视化界面:适合一次性导入、数据量可控

  2. 写程序:for 循环,建议分批,不要一把梭哈(可以用接口来控制)要保证可控、幂等,注意线上环境和测试环境是有区别的

    导入 1000 万条,for i 1000w

  3. 执行 SQL 语句:适用于小数据量

  4. 一次性任务main方法

  5. 定时任务

定时任务:

启动类上加注解

image-20220910155820598

插入数据

@Component
public class InsertUser {
    @Resource
    private UserMapper userMapper;

    public void doInsertUser() {
        //计时工具spring的
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        final int NUM = 1000;
        for (int i = 0; i < NUM; i++) {
            User user = new User();
            user.setUsername("假用户");
            user.setUserAccount("fake");
            user.setTags("");
            user.setAvatarUrl("https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/3925/202209101442967.jpg");
            user.setGender(0);
            user.setUserPassword("123123");
            user.setEmail("213213@qq.com");
            user.setUserStatus(0);
            user.setPhone("123123");
            user.setUserRole(0);
            user.setPlanetCode("111");
            userMapper.insert(user);
        }
        stopWatch.stop();
        stopWatch.getTotalTimeMillis();
    }
}

计时工具spring的

StopWatch

怎么运行,不能main方法,会报错

因为用到了mapper,springboot没启动,注入不进来

image-20220910164851498

image-20220910164759074

指定最大值, 相当于只执行一次

在方法上加注解

 @Scheduled(initialDelay = 5000,fixedRate = Long.MAX_VALUE)

就可以只执行一次

或者写在单元测试里,但是在打包时候会执行一次单元测试,每次打包就会插入数据

package com.bo.partner.service.impl;

import com.bo.partner.mapper.UserMapper;
import com.bo.partner.model.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;

/**
* @author: bo
* @date: 2022/9/10
* @description:
*/
@SpringBootTest
public class InsertUserTest {
    @Resource
    private UserMapper userMapper;

    @Test
    public void doInsertUser() {
        //计时工具spring的
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        final int NUM = 1000;
        for (int i = 0; i < NUM; i++) {
            User user = new User();
            user.setUsername("假用户");
            user.setUserAccount("fake");
            user.setTags("");
            user.setAvatarUrl("https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/3925/202209101442967.jpg");
            user.setGender(0);
            user.setUserPassword("123123");
            user.setEmail("213213@qq.com");
            user.setUserStatus(0);
            user.setPhone("123123");
            user.setUserRole(0);
            user.setPlanetCode("111");
            userMapper.insert(user);
        }
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
    }
}

时间主要是花费在==建立和释放数据库连接(使用批量查询可以解决)==for循环是绝对线性的(并发)

批量查询

mybatisplus的saveBatch();

        final int NUM = 1000;
        List<User> users = new ArrayList<>();

        for (int i = 0; i < NUM; i++) {
            User user = new User();
            user.setUsername("假用户");
            user.setUserAccount("fake");
            user.setTags("");
            user.setAvatarUrl("https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/3925/202209101442967.jpg");
            user.setGender(0);
            user.setUserPassword("123123");
            user.setEmail("213213@qq.com");
            user.setUserStatus(0);
            user.setPhone("123123");
            user.setUserRole(0);
            user.setPlanetCode("111");
            users.add(user);
            /*userMapper.insert(user);*/

        }
        userService.saveBatch(users, 100);

再次优化

并发要注意执行的先后顺序没有影响不要用到非并发类的集合

image-20220910194630170

@Test
    public void doConcurrencyInsertUser() {
        //计时工具spring的
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        final int NUM = 100000;
        int j = 0;
        //10万分10组
        List<CompletableFuture<Void>> futureList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            List<User> users = Collections.synchronizedList(new ArrayList<>());
            while (true) {
                j++;
                User user = new User();
                user.setUsername("假用户");
                user.setUserAccount("fake");
                user.setTags("");
                user.setAvatarUrl("https://xingqiu-tuchuang-1256524210.cos.ap-shanghai.myqcloud.com/3925/202209101442967.jpg");
                user.setGender(0);
                user.setUserPassword("123123");
                user.setEmail("213213@qq.com");
                user.setUserStatus(0);
                user.setPhone("123123");
                user.setUserRole(0);
                user.setPlanetCode("111");
                users.add(user);
                if (j % 10000 == 0) {
                    break;
                }
            }
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                userService.saveBatch(users, 10000);
            });
            futureList.add(future);
        }
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[]{})).join();
        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis());
        }

从自己的线程池取

private ExecutorService executorService = new ThreadPoolExecutor(60,1000,10000,TimeUnit.MINUTES,new ArrayBlockingQueue<>(10000));
  1. CPU密集型:分配的核心线程数=CPU - 1
  2. IO密集型:分配的核心线程数可以大于 CPU核数

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 10:59:34  更:2022-09-13 11:00:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 12:42:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码