MySQL数据库导入100万数据不同方式的性能差异

本文将介绍MySQL数据库导入100万数据的三种方式性能比较。

三种方式分别为:

(1)逐条INSERT

(2)批量INSERT提交

(3)通过mysql自带的load data命令

应用场景:假设需要向100万个号码发送短信,收到了100万个号码txt文件,现需要将号码导入到数据库,通过短信系统发送短信。向数据库导入数据的场景还有很多,比如在新老系统切换的时候,需要将老系统的数据迁移导入到新系统,这些都可能涉及到大量数据导入的问题。

首先,我们先准备数据库表、100万个号码、生成insert语句的java代码、批量向数据库提交insert语句的java代码。

(1)数据库表如下:

(2) 生成100万个号码

package com.fd.demo.common;import org.springframework.stereotype.Component;import java.io.*;/*** @Author: thinkpad* @Date: 2023-12-30 9:23*/
@Component
public class TelephoneGenerate {/*** 生成号码个数* @param count*/public void generate(int count) throws Exception{String telephoneBase = "13900000000";if(count > 100000000){throw new Exception("号码生成个数最大不能超过1亿");}String fileName = "telephoneGenerate.txt";File file = new File(fileName);if(!file.exists()){file.createNewFile();}// demo代码 不考虑异常情况FileOutputStream fileOutputStream = new FileOutputStream(file);OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);for(int i = 0; i < count; i++){String str = String.valueOf(i);String telephone = telephoneBase.substring(0, 11-str.length()) + str;bufferedWriter.write(telephone);bufferedWriter.write("\n");}bufferedWriter.flush();bufferedWriter.close();outputStreamWriter.close();fileOutputStream.close();}public static void main(String[] args) throws Exception {TelephoneGenerate telephoneGenerate = new TelephoneGenerate();long beginTime = System.currentTimeMillis();telephoneGenerate .generate(1000000);long endTime = System.currentTimeMillis();System.out.println("cost time: " + (endTime - beginTime) + "ms");}
}

(3) 生成100万条insert语句

package com.fd.demo.common;import org.springframework.stereotype.Component;import java.io.*;
import java.util.Objects;/*** @Author: thinkpad* @Date: 2023-12-30 9:22*/
@Component
public class MySQLInsertGenerate {/*** 生成insert语句*/public void generateInsertSQL() throws Exception{String fileName = "telephoneGenerate.txt";File file = new File(fileName);// demo代码 不考虑异常情况FileInputStream fileInputStream = new FileInputStream(file);InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String sqlFileName = "telephoneInsertSQL.txt";File sqlFile = new File(sqlFileName);FileOutputStream fileOutputStream = new FileOutputStream(sqlFile);OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);BufferedWriter bufferedWriter = new BufferedWriter(outputStreamWriter);String telephone = bufferedReader.readLine();while(!Objects.isNull(telephone) && !"".equals(telephone)){TelephoneRecvListVO telephoneRecvListVO = new TelephoneRecvListVO();telephoneRecvListVO.setId(IdWorker.nextId()); //雪花算法生成idtelephoneRecvListVO.setAppId(2);telephoneRecvListVO.setAppName("demo");telephoneRecvListVO.setTemplateId(2);telephoneRecvListVO.setTemplateContent("测试短信内容发送");telephoneRecvListVO.setTelephoneList(telephone); // 如果有多个号码,以短号隔开telephoneRecvListVO.setCreateDate("20231230");telephoneRecvListVO.setCreateTime("170000");telephoneRecvListVO.setStatus("9"); // 9初始状态 0已发送 1发送失败 2发送中String insertSql = generate(telephoneRecvListVO);bufferedWriter.write(insertSql);bufferedWriter.write("\n");telephone = bufferedReader.readLine();}bufferedWriter.flush();bufferedWriter.close();outputStreamWriter.close();fileOutputStream.close();inputStreamReader.close();fileInputStream.close();}// 可以使用反射进行组装private String generate(TelephoneRecvListVO telephoneRecvListVO){StringBuilder sb = new StringBuilder();sb.append("insert into recv_list(ID, APP_ID, APP_NAME, TEMPLATE_ID, TEMPLATE_CONTENT, TELEPHONE_LIST, CREATE_DATE, CREATE_TIME, STATUS) values(");sb.append(telephoneRecvListVO.getId());sb.append(",");sb.append(telephoneRecvListVO.getAppId());sb.append(",");sb.append("'" + telephoneRecvListVO.getAppName() + "'");sb.append(",");sb.append(telephoneRecvListVO.getTemplateId());sb.append(",");sb.append("'" + telephoneRecvListVO.getTemplateContent() + "'" );sb.append(",");sb.append("'" + telephoneRecvListVO.getTelephoneList() + "'" );sb.append(",");sb.append("'" + telephoneRecvListVO.getCreateDate() + "'");sb.append(",");sb.append("'" + telephoneRecvListVO.getCreateTime() + "'");sb.append(",");sb.append("'" + telephoneRecvListVO.getStatus() + "'");sb.append(");");return sb.toString();}public static void main(String[] args) throws Exception {MySQLInsertGenerate generate = new MySQLInsertGenerate();long beginTime = System.currentTimeMillis();generate.generateInsertSQL();long endTime = System.currentTimeMillis();System.out.println("cost time: " + (endTime - beginTime) + " ms");}
}

(4)单笔向recv_list插入数据

package com.fd.demo.mysqlinsert;import java.io.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Objects;/*** @Author: thinkpad* @Date: 2023-12-30 19:07*/
public class SingleInsert {public void singleInsert() throws Exception {File file = new File("telephoneInsertSQL.txt");FileInputStream fileInputStream = new FileInputStream(file);InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);try{Connection conn = MySqlJDBC.getConnection();String sql = bufferedReader.readLine();long currentIndex = 1;while(!Objects.isNull(sql) && !"".equals(sql)){if(currentIndex%10000 == 0){System.out.println("Current Index = " + currentIndex);}PreparedStatement ps = conn.prepareStatement(sql);ps.execute();sql = bufferedReader.readLine();currentIndex++;}}catch (Exception e){e.printStackTrace();}bufferedReader.close();inputStreamReader.close();fileInputStream.close();}public static void main(String[] args) throws Exception {SingleInsert singleInsert = new SingleInsert();long beginTime = System.currentTimeMillis();singleInsert.singleInsert();long endTime = System.currentTimeMillis();System.out.println("cost time: " + (endTime - beginTime) + " ms");}
}

单笔总共花费时间:将近31小时

(5)批量向recv_list插入数据(每10000笔提交一次事务)

package com.fd.demo.mysqlinsert;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.Statement;
import java.util.Objects;/*** @Author: thinkpad* @Date: 2023-12-30 19:23*/
public class BatchInsert {public void batchInsert() throws Exception{File file = new File("telephoneInsertSQL.txt");FileInputStream fileInputStream = new FileInputStream(file);InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);try{Connection conn = MySqlJDBC.getConnection();Statement statement = conn.createStatement();conn.setAutoCommit(false); // 批量插入主要是不自动提交事务,String sql = bufferedReader.readLine();long currentIndex = 1;while(!Objects.isNull(sql) && !"".equals(sql)){statement.executeUpdate(sql);if(currentIndex % 10000 == 0){System.out.println("currentIndex = " + currentIndex);conn.commit();}sql = bufferedReader.readLine();currentIndex++;}}catch (Exception e){e.printStackTrace();}bufferedReader.close();inputStreamReader.close();fileInputStream.close();}public static void main(String[] args) throws Exception {BatchInsert batchInsert = new BatchInsert();long beginTime = System.currentTimeMillis();batchInsert.batchInsert();long endTime = System.currentTimeMillis();System.out.println("cost time: " + (endTime - beginTime) + " ms");}
}

批量插入数据,仅花费了4分钟,完全秒杀单笔插入的效率。

(6)使用mysql的load data命令

load data infile 'G:/idea_workspace/MySQLPerformance/telephoneImportSQL.txt' 
into table recv_list fields terminated by ',' enclosed by '"' 
lines terminated by '\n';

如果在执行的过程中发生以下错误:

ERROR 1261 (01000):Row 1 doesn't contain data for all colums

这是因为sql_mode 被设为了 strict 模式, 要想继续导入需要把“strict_trans_tables” 从 sql_mode 中去掉.

查看 MySQL 当前连接的 sql_mode

mysql> show variables like 'sql_mode';

临时修改sql_mode

mysql> set sql_mode='';

 使用load data命令花了2分26秒的时间,比批量导入快了近一倍。

通过上述比较,可以看出load data命令的性能最佳,其次是批量导入,最差的是单笔插入。

上述所有代码工程见 https://download.csdn.net/download/flyingcloude/88681843?spm=1001.2014.3001.5503

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/586887.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gitLab页面打tag操作步骤

作者&#xff1a;moical 链接&#xff1a;gitLab页面打tag简单使用 - 掘金 (juejin.cn) 来源&#xff1a;稀土掘金 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 ---------------------------------------------------------------------…

RK3568测试tdd

RK3568测试tdd 一、门禁取包二、烧录三、跑tdd用例四、查看结果参考资料 一、门禁取包 右键复制链接&#xff0c;粘贴下载&#xff1b;解压到文件夹&#xff1b; 二、烧录 双击\windows\RKDevTool.exe打开烧写工具&#xff0c;工具界面击烧写步骤如图所示&#xff1a; 推荐…

二叉树BFS

前置知识 二叉树节点的定义 二叉树是递归定义的 /*** Definition for a binary tree node.&#xff08;LeetCode&#xff09;*/public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode…

【java爬虫】获取个股详细数据并用echarts展示

前言 前面一篇文章介绍了获取个股数据的方法&#xff0c;本文将会对获取的接口进行一些优化&#xff0c;并且添加查询数据的接口&#xff0c;并且基于后端返回数据编写一个前端页面对数据进行展示。 具体的获取个股数据的接口可以看上一篇文章 【java爬虫】基于springbootjd…

Android : 使用GestureOverlayView进行手势识别—简单应用

示例图&#xff1a; GestureOverlayView介绍&#xff1a; GestureOverlayView 是 Android 开发中用于识别和显示手势的视图组件。它允许用户在屏幕上绘制手势&#xff0c;并且应用程序可以检测和响应这些手势。以下是关于 GestureOverlayView 的主要特点&#xff1a; 手势识别…

nodejs+vue+微信小程序+python+PHP特困救助供养信息管理系统-计算机毕业设计推荐

通过走访某特困救助供养机构实际情况&#xff0c;整理特困救助供养机构管理的业务流程&#xff0c;分析当前特困救助供养机构管理存在的各种问题&#xff0c;利用软件开发思想对特困救助供养机构特困救助供养机构管理进行系统设计分析。通过服务端程序框架进行设计&#xff0c;…

MFC - 给系统菜单(About Dialog)发消息

文章目录 MFC - 给系统菜单(About Dialog)发消息概述笔记resource.h菜单的建立菜单项的处理MSDN上关于系统菜单项值的说法END MFC - 给系统菜单(About Dialog)发消息 概述 做了一个对话框程序, 在系统菜单(在程序上面的标题栏右击)中有"关于"的菜单. 这个是程序框架…

【MySQL】事务Transaction

1. 事务的概念 事务是什么 在业务逻辑中使用sql&#xff0c;面对一些较复杂的场景&#xff0c;是需要多个sql语句组合起来实现的。如&#xff1a;银行的转账业务&#xff0c;若客户A要转账100元给客户B&#xff0c;就要两条sql&#xff1a;A余额减100&#xff0c;B余额加100&a…

ES6语法(五)封装模块化公共工具函数、引入npm包 ,并上传到npm中进行下载

1. 模块化 模块化是指将一个大的程序文件&#xff0c;拆分为许多小的文件&#xff08;模块&#xff09;&#xff0c;然后将小的文件组合起来。 1.1. 优点 &#xff08;1&#xff09;防止命名冲突 &#xff08;2&#xff09;代码复用 &#xff08;3&#xff09;高维护性 &…

【CFP-专栏2】计算机类SCI优质期刊汇总(含IEEE/Top)

一、计算机区块链类SCI-IEEE 【期刊概况】IF:4.0-5.0, JCR2区&#xff0c;中科院2区&#xff1b; 【大类学科】计算机科学&#xff1b; 【检索情况】SCI在检&#xff1b; 【录用周期】3-5个月左右录用&#xff1b; 【截稿时间】12.31截稿&#xff1b; 【接收领域】区块链…

利用idea+ jclasslib插件查看和分析 Java 类文件的字节码

jclasslib介绍 jclasslib 插件是一个用于 IntelliJ IDEA 的工具&#xff0c;它允许开发者在集成开发环境&#xff08;IDE&#xff09;内直接查看和分析 Java 类文件的字节码。这个插件尤其对于想要深入了解 Java 字节码、类加载机制、以及 Java 虚拟机&#xff08;JVM&#xf…

网络基础操作练习

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 手把手教你操作华为设备&#xff0c;新手必看。 实验拓扑图 关于命令行视图 1&#xff09;用户视图 <Huawei> 2&#xff09;系统视图 [Hu…

C++初阶(类中的默认成员函数)

呀哈喽&#xff0c;我是结衣 今天给大家带来的是类里面的默认成员函数&#xff0c;一共有六个默认的成员函数哦&#xff0c;包括构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;运算符重载函数&#xff0c;const成员函数&#xff0c;那么正篇开始。 文章目…

Go语言中的性能考虑和优化

优化您的Go代码以达到最佳性能 性能优化是软件开发的关键方面&#xff0c;无论您使用哪种编程语言。在这篇文章中&#xff0c;我们将探讨Go语言中的性能考虑和优化&#xff0c;Go是一种以其效率而著称的静态类型和编译语言。我们将深入探讨三个关键领域&#xff1a;分析并发代…

pytorch01:概念、张量操作、线性回归与逻辑回归

目录 一、pytorch介绍1.1pytorch简介1.2发展历史1.3pytorch优点 二、张量简介与创建2.1什么是张量&#xff1f;2.2Tensor与Variable2.3张量的创建2.3.1 直接创建torch.tensor()2.3.2 从numpy创建tensor 2.4根据数值创建2.4.1 torch.zeros()2.4.2 torch.zeros_like()2.4.3 torch…

开源可观测性平台Signoz(四)【链路监控及数据库中间件监控篇】

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 前文链接&#xff1a; ​​开源可观测性平台Signoz系列&#xff08;一&#xff09;【开篇】​​ ​​开源可观测性平台Signoz&…

CSS之元素转换

我想大家在写代码时有一个疑问&#xff0c;块级元素可以转换成其他元素吗&#xff1f; 让我为大家介绍一下元素转换 1.display:block(转换成块元素) display&#xff1a;block可以把我们的行内元素或者行内块元素转换成块元素 接下来让我为大家演示一下&#xff1a; <!DO…

tcpdump出现permission denied

在使用tcpdump -i eth0 src host 192.168.0.184 and ip and port 22 -nn -w ping.pacp命令抓包并把抓到的数据保存到ping.pacp时&#xff0c;出现了权限错误的报错。但实际上我这里用的是root用户执行的命令。 查阅man手册发现: 在tcpdump中&#xff0c;-Z选项用于在启动数据…

CSS 动态提示框

​​ <template> <div class"terminal-loader"><div class"terminal-header"><div class"terminal-title">提示框</div><div class"terminal-controls"><div class"control close"…

【Matlab】BP 神经网络时序预测算法

资源下载&#xff1a; https://download.csdn.net/download/vvoennvv/88681507 一&#xff0c;概述 BP 神经网络是一种常见的人工神经网络&#xff0c;也是一种有监督学习的神经网络。其全称为“Back Propagation”&#xff0c;即反向传播算法。BP 神经网络主要由输入层、隐藏层…