1.背景:
最近博主正在研究mysql在大数据量下sql执行时各个方面的性能情况,以及执行速度.优化方式和优化后的结果等,这个时候一个大数量的表就是我所面临的必需品了
2 .解决办法
这里首先我能想到的就是,多线程+批量插入去解决这个问题,随后我参考了很多文章,大致的解决思路也是一样的,就是采用的方式略有不同,有使用原生的, 有使用mybatis的,有使用存储过程的
本着怎么简单怎么来的办法,我的解决方法如下
public void add1000W() {
try {
//获取开始时间
long start = DateUtil.currentSeconds();
// 指定线程数量
int numThreads = 10;
// 指定每个线程批量插入的数据量
int batchSize = 1000;
// 指定要插入的总记录数
int totalRecords = 10000000;
//每个线程所负责的数据量
int count = totalRecords / numThreads;
//创建线程池
Thread[] threads = new Thread[numThreads];
//创建启动线程
for (int i = 0; i < numThreads; i++) {
threads[i] = new InsertThread(testService,batchSize,0,count);
threads[i].start();
}
// 等待所有线程执行完毕
for (int i = 0; i < numThreads; i++) {
threads[i].join();
}
long end = DateUtil.currentSeconds();
System.out.println(totalRecords + "条数据插入完毕,用时===>" + (end - start) + "秒");
}catch (Exception e){
e.printStackTrace();
}
}
static class InsertThread extends Thread{
//定义私有变量,用于保存临时操作内容
private TestService service;
private int batchSize;
private int startIndex;
private int count;
public InsertThread() {
}
//创建一个有参构造,用于赋值
public InsertThread(TestService testService,int batchSize, int startIndex, int count) {
this.batchSize = batchSize;
this.startIndex = startIndex;
this.count = count;
this.service = testService;
}
@Override
public void run() {
try {
List<TestModel> list = new ArrayList<>();
TestModel testModel = new TestModel();
for (int i = startIndex; i < count; i++) {
testModel.setId(IdUtil.fastSimpleUUID());
testModel.setSex(i % 2 == 0 ? 0 : 1);
testModel.setName(i % 2 == 0 ? RandomInfo.getRandomBoyName() : RandomInfo.getRandomGirlName());
testModel.setAge(RandomUtil.randomNumber(100));
testModel.setAddress(RandomInfo.getRandomAddress());
list.add(testModel);
if (i % batchSize == 0){
service.saveBatch(list);
list.clear();
System.out.println(batchSize + "条数据插入完成");
}
}
if (list.size() != 0){
service.saveBatch(list);
list.clear();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
3 .优化方案
1.环境
我测试的时候使用的云服务器,最大带宽1Mbit/s
2.测试的结果
当时大约执行了12个小时左右才插入完毕,由于我这个是个人需要,没有时间要求,就没有过分的去深究这个时间问题
3.个人分析影响性能的因素
- 对象的频繁创建
- 线程的数量
- 要插入的数据量
- 对象中参数的赋值,我这里为了更加的接近于线上真实环境,所以创建的数据都是通过工具类实时生成的,这也是影响效率的主要因素
- 电脑的配置
- 网速
- 框架问题
- 数据库的配置问题
- 等等很多因素,有能力的大佬可以继续深入探索
4 .解决方案
- 减少创建对象,索性直接不使用对象,采用拼接sql的方式
- 多开几个线程,这个要根据电脑的性能决定,如果性能跟不上开多了意义不大
- 合理减少插入的数据量
- 不使用操作繁琐的工具类创建参数,一切采用简单方式
- 升级电脑配置
- 增加带宽
- 避免使用框架,不论是干什么,使用的技术越接近底层速度越快
- 可以在合理的情况下,调整数据库的配置文件中的配置
- 更多的解决方案期待各位大佬的补充