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,一经查实,立即删除!

相关文章

neo4j运维管理

管理数据库 概念 Neo4j 5(从v4.0)&#xff0c;可以同时创建和使用多个活动数据库。 DBMS Neo4j是一个数据库管理系统(DBMS)&#xff0c;能够管理多个数据库。DBMS可以管理一个独立的服务器&#xff0c;也可以管理集群中的一组服务器。 实例 Neo4j实例是运行Neo4j服务器代…

gitLab页面打tag操作步骤

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

Linux lpr命令教程:如何使用lpr命令打印文件(附案例详解和注意事项)

Linux lpr命令介绍 lpr命令在Unix-like操作系统中用于提交打印任务。如果在命令行中指定了文件名&#xff0c;那么这些文件将被发送到指定的打印机&#xff08;如果没有指定目的地&#xff0c;则发送到默认目的地&#xff09;。如果命令行中没有列出文件&#xff0c;lpr将从标…

RK3568测试tdd

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

1229-方法引用(简化lambda)-stream流-单元测试-单例模式

方法引用stream流单元测试&#xff08;junit&#xff09;单例模式 方法引用 概念&#xff1a;对特殊的lambda简化的一种语法 使用时机&#xff1a;&#xff08;&#xff09;-> {lambda体} 特殊的lambda&#xff1a;当lambda体只有1句代码&#xff0c;并且这句代码是在调用…

二叉树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…

Leetcode的AC指南 —— 双指针:18. 四数之和

摘要&#xff1a; Leetcode的AC指南 —— 双指针&#xff1a;18. 四数之和。题目介绍&#xff1a;给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;…

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

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

Canal的学习

Canal 基本概念整合SpringBoot 基本概念 Canal是一个基于MySQL数据库增量日志解析&#xff0c;提供增量数据订阅和消费&#xff0c;支持将增量数据投递到下游消费者&#xff08;如Kafka、RocketMQ等&#xff09;或者存储&#xff08;如 Elasticsearch、HBase 等&#xff09;的…

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

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

Python基础语法笔记 tkinter的简单使用

语法 物质 动态类型语言,不需要声明类型 数字 类型int float bool 操作 //整除 **幂 字符串 str1 "Hello python" str2 "world" print(str1 * 3) # 重复输出 print(str1[1]) # 索引访问 print(str1 " " str2) # 拼接 print(str1[2…

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

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

java常见面试题:请解释一下Java中的常用分布式框架,如Spring Boot、Dubbo等。

下面我将详细介绍Java中的两个常用分布式框架&#xff1a;Spring Boot和Dubbo。 1. Spring Boot Spring Boot是一个用于创建独立、可运行的、生产级别的Spring应用程序的框架。它简化了Spring应用程序的创建和部署&#xff0c;使得开发人员能够专注于编写业务逻辑&#xff0c…

【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…

MongoDB聚合:$replaceRoot

定义 $replaceRoot使用指定的文档替换输入文档。该操作可替换输入文档的所有字段&#xff0c;包括_id字段。可以将内嵌文档提升到顶层&#xff0c;可以为提升文档创建新文档。 注意&#xff1a; 从MongoDB4.2开始增加了$replaceWith&#xff0c;执行与$replaceRoot类似的动作…

网络基础操作练习

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