Mysql5.7, 千万数据快速插入解决方案( JDBC方式, 百秒搞定!!!)
最近在弄一件任务,要求测试一下从文本中读取数据,然后向mysql表中插入。要求用JDBC线程导入。要求效率。
环境说明:
数据量 : 10058624条 (大约一千零6万条数据,本地机器运行)
数据大小 : 1093.56MB (1.1G)
MYSQL版本 : 5.7 (装在服务器上)
MYSQL引擎: InnoDB
MYSQL未做任何优化,配置如图:
一、数据文件读取
因为项目要求读取的是dbf文件,数据量比较大,所以单独写了一个程序,测试一下数据读取用多久。
未做任何保存、配置,只是将数据循环遍历一边。 计算出时间:
数据量 :10058624条 (大约一千零6万条数据 ,截图中没有显示)
读取用时 : 19s
二、 代码优化。(mysql配置不动)
方式一: 传统方式
输出时间:
Program running index : 10000 use : 7 s
Program running index : 20000 use : 15 s
Program running index : 30000 use : 21 s
Program running index : 40000 use : 28 s
Program running index : 50000 use : 34 s
Program running index : 60000 use : 41 s
Program running index : 70000 use : 48 s
Program running index : 80000 use : 54 s
Program running index : 90000 use : 61 s
Program running index : 100000 use : 69 s
Program running index : 500000 use : 346 s
Program running index : 1000000 use : 693 s
Program running index : 1500000 use : 1042 s
Program running index : 2000000 use : 1402 s
Program running index : 2500000 use : 1757 s
总结:
运行很慢,平均插入一万条需要耗时7s,
那么一千万条, 预计需要7000s 。 ( 117 min , 即将近两个小时 。。 )
方式二: 将sql中的多个value值,拼在一起,进行插入操作。
实例:
insert into `tableName` (`id`,`name`) values ('1', '张三') ;
insert into `tableName` (`id`,`name`) values ('2', '李斯') ;
insert into `tableName` (`id`,`name`) values ('3', '王五') ;
变成:
insert into `tableName` (`id`,`name`) values ('1', '张三') , ('2', '李斯') , ('3', '王五') ;
代码片段截图:
运行结果分析:
batchSize : 多少条数据,拼成一条SQL
submitSize : 多少条SQL提交一次
处理数据完成 ==> batchSize : 500 , submitSize: 1 插入数据总条数 size : 10058624 total use : 190 s , 处理速度: 52940 条/s
处理数据完成 ==> batchSize : 500 , submitSize: 5 插入数据总条数 size : 10058624 total use : 144 s , 处理速度: 69851 条/s
处理数据完成 ==> batchSize : 500 , submitSize: 10 插入数据总条数 size : 10058624 total use : 137 s , 处理速度: 73420 条/s
处理数据完成 ==> batchSize : 1000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 161 s , 处理速度: 62475 条/s
处理数据完成 ==> batchSize : 1000 , submitSize: 5 插入数据总条数 size : 10058624 total use : 134 s , 处理速度: 75064 条/s
处理数据完成 ==> batchSize : 1000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 133 s , 处理速度: 75628 条/s
处理数据完成 ==> batchSize : 5000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 144 s , 处理速度: 69851 条/s
处理数据完成 ==> batchSize : 5000 , submitSize: 5 插入数据总条数 size : 10058624 total use : 136 s , 处理速度: 73960 条/s
处理数据完成 ==> batchSize : 5000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 134 s , 处理速度: 75064 条/s
处理数据完成 ==> batchSize : 10000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 143 s , 处理速度: 70340 条/s
处理数据完成 ==> batchSize : 10000 , submitSize: 5 插入数据总条数 size : 10058624 total use : 138 s , 处理速度: 72888 条/s
处理数据完成 ==> batchSize : 10000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 137 s , 处理速度: 73420 条/s
处理数据完成 ==> batchSize : 100000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 137 s , 处理速度: 73420 条/s
处理数据完成 ==> batchSize : 100000 , submitSize: 5 插入数据总条数 size : 10058624 total use : 136 s , 处理速度: 73960 条/s
处理数据完成 ==> batchSize : 100000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 135 s , 处理速度: 74508 条/s
处理数据完成 ==> batchSize : 1000000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 148 s , 处理速度: 67963 条/s
总结:
最快处理速度 :
每1000条数据拼一条SQL语句,批量提交10条SQL语句,
插入数据总条数 size : 10058624 total use : 133 s , 处理速度: 75628 条/s
总结:
代码效率明显会比第一次提升N倍,推荐用这种方式进行插入。
注:
种方式会报异常,
Packet for query is too large (1117260 > 1048576). You can change this value on the server by setting the max_allowed_packet' variable.
原因&解决方案:
Sql语句过长,超过限制,需要调整 mysql 参数:
修改 /etc/my.comf 文件, 添加参数: max_allowed_packet = 128M 。( 大小可以自己测试 )
方式三、改写所有 insert into 语句为 insert delayed into
这个insert delayed不同之处在于:立即返回结果,后台进行处理插入。
测试速度:
处理数据完成 ==> batchSize : 1000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 138 s , 处理速度: 72888 条/s
处理数据完成 ==> batchSize : 1000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 139 s , 处理速度: 72364 条/s
总结:
性能并没有发现明显提升...............
三、数据库参数优化
这次修改了下面四个配置项:
1)将 innodb_flush_log_at_trx_commit 配置设定为0;按过往经验设定为0,插入速度会有很大提高。
当
innodb_flush_log_at_trx_commit=0
时, log buffer将每秒一次地写入log file, 并且log file的flush(刷新到disk)操作同时进行. 此时, 事务提交是不会主动触发写入磁盘的操作.当
innodb_flush_log_at_trx_commit=1
时(默认), 每次事务提交时, MySQL会把log buffer的数据写入log file, 并且将log file flush(刷新到disk)中去.当
innodb_flush_log_at_trx_commit=2
时, 每次事务提交时, MySQL会把log buffer的数据写入log file, 但不会主动触发flush(刷新到disk)操作同时进行. 然而, MySQL会每秒执行一次flush(刷新到disk)操作.然而, 每秒flush并不能确保100%每秒发生, 因为os调度问题.
默认的1可以获得更好地数据安全, 但性能会打折扣. 不过非1时, 在遇到crash可能会丢失1秒的事务; 设置为0时, 任何mysqld进程crash会丢失上1秒的事务; 设置为2时, 任何os crash或者机器掉电会丢失上1秒的事务; InnoDB的crash recovery运行时会忽略这些数据.
2)将 innodb_autoextend_increment 配置由于默认8M 调整到 128M
此配置项作用主要是当tablespace 空间已经满了后,需要MySQL系统需要自动扩展多少空间,每次tablespace 扩展都会让各个SQL 处于等待状态。增加自动扩展Size可以减少tablespace自动扩展次数。
3)将 innodb_log_buffer_size 配置由于默认1M 调整到 16M
此配置项作用设定innodb 数据库引擎写日志缓存区;将此缓存段增大可以减少数据库写数据文件次数。
4)将 innodb_log_file_size 配置由于默认 8M 调整到 128M
此配置项作用设定innodb 数据库引擎UNDO日志的大小;从而减少数据库checkpoint操作。
经过以上调整,系统插入速度由于原来10分钟几万条提升至1秒1W左右;注:以上参数调整,需要根据不同机器来进行实际调整。特别是 innodb_flush_log_at_trx_commit、innodb_log_buffer_size和 innodb_log_file_size 需要谨慎调整;因为涉及MySQL本身的容灾处理。
5)修改 max_allowed_packet
sql语句过长会报错,增加长度。
最终修改参数:
max_allowed_packet = 128M
innodb_flush_log_at_trx_commit = 0
innodb_log_buffer_size = 16M
innodb_autoextend_increment = 128M
innodb_log_file_size = 128M
innodb_buffer_pool_size = 4096M
测试运行结果:
处理数据完成 ==> batchSize : 1000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 134 s , 处理速度: 75064 条/s
处理数据完成 ==> batchSize : 1000 , submitSize: 5 插入数据总条数 size : 10058624 total use : 129 s , 处理速度: 77973 条/s
处理数据完成 ==> batchSize : 1000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 128 s , 处理速度: 78583 条/s
处理数据完成 ==> batchSize : 10000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 139 s , 处理速度: 72364 条/s
处理数据完成 ==> batchSize : 10000 , submitSize: 5 插入数据总条数 size : 10058624 total use : 138 s , 处理速度: 72888 条/s
处理数据完成 ==> batchSize : 10000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 138 s , 处理速度: 72888 条/s
处理数据完成 ==> batchSize : 100000 , submitSize: 1 插入数据总条数 size : 10058624 total use : 137 s , 处理速度: 73420 条/s
处理数据完成 ==> batchSize : 100000 , submitSize: 5 插入数据总条数 size : 10058624 total use : 136 s , 处理速度: 73960 条/s
处理数据完成 ==> batchSize : 100000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 135 s , 处理速度: 74508 条/s
四、更换数据库表引擎
1、采用MyISAM 数据引擎
建表语句:
DROP TABLE IF EXISTS `DBF_MyISAM`;
CREATE TABLE `DBF_MyISAM` (
`GDDM` varchar(255) DEFAULT NULL,
`GDXM` varchar(255) DEFAULT NULL,
`BS` varchar(255) DEFAULT NULL,
`MJBH` varchar(255) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
执行效果: ( 最快用时97 s )
处理数据完成 ==> batchSize : 1000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 97 s , 处理速度: 103697 条/s
处理数据完成 ==> batchSize : 5000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 106 s , 处理速度: 94892 条/s
处理数据完成 ==> batchSize : 10000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 107 s , 处理速度: 94005 条/s
处理数据完成 ==> batchSize : 100000 , submitSize: 10 插入数据总条数 size : 10058624 total use : 107 s , 处理速度: 94005 条/s
总结: 采用MyISAM 数据引擎 性能上会比用InnoDB 快 ,性能提升 25% 左右。
最快时间为97s ,如果去除掉读取文件的时间19s ,
插入10058624 (一千零五万八)条数据,只需要 78 s 。 因机器、网络不同,时间略有差异。
分区,多线程,读写分离等技术都可以提高数据插入数据,本篇文章先不做概述
如果有不正确或者更好的解决方案, 欢迎指正,不胜感谢.......
Mysql5.7, 千万数据快速插入解决方案( JDBC方式, 百秒搞定!!!)相关推荐
- mvvm怎么让光标制定属性的文本框_Word怎么快速制作斜线表头?10秒搞定,表格颜值直线上升...
Word怎么快速制作斜线表头?这个问题可能困扰着很多刚进入职场的小伙伴.不管是文员是一线工作人员,工作中或多或少都会涉及斜线表头的制作. 因此,今天就给大家分享一下制作斜线表头的方法,而在Word中斜 ...
- excel一列求和_Excel超实用小技巧:快速求和和对齐,一秒搞定
相信各位老师在办公中,经常会运用到excel表格制作,常规的表格制作操作复杂,且浪费时间,掌握一些excel制作小技巧,可以提升效率且操作简单,老师们可以学一学; 如何快速求和? 老师们在制作表格过程 ...
- PLSQL如何将千万数据快速插入到另一张表中_数据库设计中的 9 大常见错误
作为数据库设计人员,当我们负责数据库项目时,在数据库设计以及把数据库部署到生产环境的过程中可能会遇到一些挑战. 其中一些问题不可避免,也无法控制.但是,其中相当一部分可以追溯到数据库设计本身的质量.我 ...
- xlwings删除数据_xlwings最全操作;10秒搞定Xlwings全套操作
import xlwings as xw app = xw.App(visible=True, add_book=False) app.display_alerts = False # 关闭一些提示信 ...
- vivo换手机云服务器,vivo玩机指南:换新机数据不用烦,云服务一步搞定
原标题:vivo玩机指南:换新机数据不用烦,云服务一步搞定 在遍地支持手机支付的网络时代,手机是其他无可替代的一样电子产品.每个品牌,每个型号,里面的功能都是不一样的.那么身为一个资深vivo手机粉, ...
- python如何高效使用excel_高效办公必备:你加班做的 Excel数据汇总,我用Python一分钟搞定!...
原标题:高效办公必备:你加班做的 Excel数据汇总,我用Python一分钟搞定! 广东优就业 IT互联网/资讯热点/技能干货 点左上方蓝字关注小U有礼物送~ 现如今无论是工作汇报.产品设计.后台设计 ...
- SQL 语句之insert语句插入数据:若表中有重复的主键或数据继续插入解决方案
已知条件:MySQL数据库 存在一张表,表名为teacher,主键为id,表中有4行数据 select * from teacher; 要求:要求使用数据库插入语句往表中插入数据,若需要插入表中的数 ...
- 数据库数据快速插入的方法
问题: 需要在mysql中造大量的数据. 方式: 一.insert 一条一条插入数据到数据库中. 不适合大量数据的插入. 二.LOAD DATA INFILE 方案 三.extend insert语句 ...
- textedit怎么插入数据_还在手动插入Excel交叉空白行?这个小技巧10秒搞定
导读:前几天有同学在后台提问,怎么快速在Excel中隔行插入一行或者多行空白行,其实在早期我们分享的小视频中有利用过类似的小技巧来制作工资条,今天我们用它来插入空白行. 文/ 芒种学院@指北针 Hel ...
最新文章
- Swift解读专题四——字符串与字符
- android控件属性
- ASP.NET制作一个简单的等待窗口
- 手把手教你做一个react-redux-demo
- nginx+tomcat 反向代理 负载均衡配置
- 如何使用nginx配置SSL证书?
- centos redis make 报错_ubuntu 18.04 搭建 redis 实验环境
- OpenGL纹理本质(三)
- Elasticsearch核心知识大纲脑图
- 13.PHP核心技术与最佳实践 --- Hash 算法与数据库实现
- PXA300平台2D图形加速器性能测试与分析
- php 颜值测试源码,微软小冰颜值测试PHP最新代码
- python开源代码题库管理_GitHub - gnu-xiaosong/Qu_system: 一款开源免费的题库系统程序,高效,安全,功能强大...
- Linux服务篇之SSH服务
- SNMP中的MIB是什么?
- LeetCode||颜色分类--给定一个包含红色、白色和蓝色,一共 *n* 个元素的数组,**原地**对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
- 技术研究:DOOM3网络模型的演化与网络架构
- 关于springboot部署服务器的步骤
- 特价机票退票费高达80% 律师称航班延误应补偿-特价机票-退票费-霸王条款
- java导入导出excel文件
热门文章
- IEC61850变电站基本通信结构-原理和模型_7建模规则中的类定义以及MMS映射模型
- 集线器与交换机的对比(基于 Cisco Packet Tracer 模拟网络)
- [docker]七、docker镜像的制作(超详细)、docker镜像结构原理、镜像的分享——harbor
- python 编程题 有n个整数、使其前面各数_有n个整数,使其前面各数顺序向后移m个位置,最后m个数变成最前面的m个数。...
- java 接口 多态 异常
- 科普:一文读懂IPv6是什么?
- (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
- 福禄克网络:突破百米布线的四种方法及优缺点分析
- HTML期末大作业:DIV简单的篮球网页制作期末作业 篮球明星科比js三级页面
- win10远程桌面连接的计算机填什么,win10远程桌面连接设置