[ 更换 ]
热门城市
北京上海广州深圳成都杭州南京武汉天津西安重庆青岛沈阳长沙大连厦门无锡福州济南宁波昆明苏州郑州长春合肥南昌哈尔滨常州烟台南宁温州石家庄太原珠海南通扬州贵阳东莞徐州大庆佛山威海洛阳淮安呼和浩特镇江潍坊桂林中山临沂咸阳包头嘉兴惠州泉州三亚赣州九江金华泰安榆林许昌新乡舟山慈溪南阳聊城海口东营淄博漳州保定沧州丹东宜兴绍兴唐山湖州揭阳江阴营口衡阳郴州鄂尔多斯泰州义乌汕头宜昌大同鞍山湘潭盐城马鞍山襄樊长治日照常熟安庆吉林乌鲁木齐兰州秦皇岛肇庆西宁介休滨州台州廊坊邢台株洲德阳绵阳双流平顶山龙岩银川芜湖晋江连云港张家港锦州岳阳长沙县济宁邯郸江门齐齐哈尔昆山柳州绍兴县运城齐河衢州太仓张家口湛江眉山常德盘锦枣庄资阳宜宾赤峰余姚清远蚌埠宁德德州宝鸡牡丹江阜阳莆田诸暨黄石吉安延安拉萨海宁通辽黄山长乐安阳增城桐乡上虞辽阳遵义韶关泸州南平滁州温岭南充景德镇抚顺乌海荆门阳江曲靖邵阳宿迁荆州焦作丹阳丽水延吉茂名梅州渭南葫芦岛娄底滕州上饶富阳内江三明淮南孝感溧阳乐山临汾攀枝花阳泉长葛汉中四平六盘水安顺新余晋城自贡三门峡本溪防城港铁岭随州广安广元天水遂宁萍乡西双版纳绥化鹤壁湘西松原阜新酒泉张家界黔西南保山昭通河池来宾玉溪梧州鹰潭钦州云浮佳木斯克拉玛依呼伦贝尔贺州通化朝阳百色毕节贵港丽江安康德宏朔州伊犁文山楚雄嘉峪关凉山雅安西藏四川广东河北山西辽宁黑龙江江苏浙江安徽福建江西山东河南湖北湖南海南贵州云南陕西甘肃青海台湾内蒙古广西宁夏香港澳门
培训资讯网 - 为兴趣爱好者提供专业的职业培训资讯知识

java 培训 MySQL 一次性插入多行数据的操作

培训 数据

一、前言

我们在操作大型数据表或者日志文件的时候经常会需要写入数据到数据库,那么最合适的方案就是数据库的批量插入。只是我们在执行批量操作的时候,一次插入多少数据才合适呢?

假如需要插入的数据有百万条,那么一次批量插入多少条的时候,效率会高一些呢?这里博主和大家一起探讨下这个问题,应用环境为批量插入数据到临时表。

java 培训 MySQL 一次性插入多行数据的操作

二、批量插入前准备

博主本地原本是循环查出来的数据,然后每 1000 条插入一次,直至完成插入操作。但是为什么要设置 1000 条呢,实不相瞒,这是因为项目里的其他批量插入都是一次插 1000 条。。汗,博主不服,所以想要测试下。

首先是查看当前数据库的版本,毕竟各个版本之间存在差异,脱离版本讲数据库就是耍流氓(以前没少耍啊):

mysql> select version();

+------------+

| version() |

+------------+

| 5.6.34-log |

+------------+

1 row in set (0.00 sec)

1、插入到数据表的字段

对于手动创建的临时表来说,字段当然是越少越好,而且字段占用的空间要尽量小一些,这样临时表不至于太大,影响表操作的性能。这里需要插入的字段是:

字段 1 int(10)

字段 2 int(10)

字段 3 int(10)

字段 4 varchar(10)

我们一共插入四个字段,分别是 3 个 int 类型的,一个 varchar 类型的,整体来说这些字段都比较小,占用的内存空间会小一些。

2、计算一行字段占用的空间

对于 innodb 引擎来说,int 类型可以存储 4 个字节,里面的 Int(M)并不会影响存储字节的大小,这个 M 只是数据的展示位数,和 mysql 的 ZEROFILL 属性有关,即在数字长度不够的数据前面填充 0,以达到设定的长度。此处不多说,想要了解的朋友可以百度一下,还是很有意思的_java培训。

varchar(10)代表可以存储 10 个字符,不管是英文还是中文,最多都是 10 个,这部分假设存储的是中文,在 utf-8mb4 下,10 个中文占用 10*4 = 40 个字节那么一行数据最多占用:4+4+4+40 = 52 字节

3、在数据里做插入操作的时候,整体时间的分配

链接耗时 (30%)

发送 query 到服务器 (20%)

解析 query (20%)

插入操作 (10% * 词条数目)

插入 index (10% * Index 的数目)

关闭链接 (10%)

从这里可以看出来,真正耗时的不是操作,而是链接,解析的过程。单条 sql 的话,会在链接,解析部分耗费大量的时间,因此速度会很慢,所以我们一般都是采用批量插入的操作,争取在一次链接里面写入尽可能多的数据,以此来提升插入的速度。但是这个尽可能多的数据是多少呢?一次到底插入多少才合适呢?

三、批量插入数据测试

开始测试,但是一开始插入多少是合适的呢,是否有上限?查询 mysql 手册,我们知道 sql 语句是有大小限制的。

1、SQL 语句的大小限制

my.ini 里有 max_allowed_packet 这个参数控制通信的 packet 大小。mysql 默认的 sql 语句的最大限制是 1M(mysql5.7 的客户端默认是 16M,服务端默认是 4M),可以根据设置查看。官方解释是适当增大 max_allowed_packet 参数可以使 client 端到 server 端传递大数据时,系统能够分配更多的扩展内存来处理。

2、查看服务器上的参数:

mysql> show variables like "%max_allowed_packet%";

+--------------------------+------------+

| Variable_name | Value |

+--------------------------+------------+

| max_allowed_packet | 33554432 |

| slave_max_allowed_packet | 1073741824 |

+--------------------------+------------+

2 rows in set (0.00 sec)

33554432 字节 = 32M ,也就是规定大小不能超过 32M。

3、计算一次能插入的最大行记录

1M 计算的话,(1024*1024)/52 ≈ 20165 ,为了防止溢出,最大可一次性插入 20000 条(根据自己的配置和 sql 语句大小计算)。那么 32M 的话就是:20000 *32 = 640000 也就是 64W 条。

4、测试插入数据比对

(1)插入 11W 条数据,按照每次 10,600,1000,20000,80000 来测试:

+---------------+

| count(c1.uin) |

+---------------+

| 110000 |

+---------------+

博主测试后,认为一次插 10 条是性能最快的,他的每条记录是 3kb,相当于我的 59 行数据,取个整数 60,那么对于这个博主是插入 10 条,对我来说插入:600,这几个值都试试。

耗时:

11W 的数据,每次插入 10 条。耗时:2.361s

11W 的数据,每次插入 600 条。耗时:0.523s

11W 的数据,每次插入 1000 条。耗时:0.429s

11W 的数据,每次插入 20000 条。耗时:0.426s

11W 的数据,每次插入 80000 条。耗时:0.352s

从这部分看,随着批量插入的增加,速度略有提升,最起码一次插 10 条应该不是最佳的。插入数据量多,减少了循环的次数,也就是在数据库链接部分的耗时有所减少,只是这个 8W 并不是极限数据,具体一次插入多少条,还有待参考。

(2)加大数据量到 24w

+---------------+

| count(c1.uin) |

+---------------+

| 241397 |

+---------------+

耗时:

24W 的数据,每次插入 10 条。耗时:4.445s

24W 的数据,每次插入 600 条。耗时:1.187s

24W 的数据,每次插入 1000 条。耗时:1.13s

24W 的数据,每次插入 20000 条。耗时:0.933s

24W 的数据,每次插入 80000 条。耗时:0.753s

一次插入 24W 反而性能最佳,这么代表我们的测试数据量依然不够。

(3)加大测试量到 42W

+---------------+

| count(c1.uin) |

+---------------+

| 418859 |

耗时:

42W 的数据,每次插入 1000 条。耗时:2.216s

42W 的数据,每次插入 80000 条。耗时:1.777s

42W 的数据,每次插入 16W 条。耗时:1.523s

42W 的数据,每次插入 20W 条。耗时:1.432s

42W 的数据,每次插入 30W 条。耗时:1.362s

42W 的数据,每次插入 40W 条。耗时:1.764s

随着插入量的增加,批量插入条数多了之后,性能是有所提升的。但是在达到 30W 以上之后,效率反而有所下降。这部分我的理解是 mysql 是要分配一定的内存给传过来的数据包使用,当批量插入的数据量到达一定程度之后,一次插入操作的开销就很耗费内存了。

个人感觉,最佳大小是 max_allowed_packet 的一半,也就是极限能插入 64W,选用 32W 也许性能会更好一些,同时也不会对 mysql 的其他操作产生太大的影响。

5、如果插入的值就是 sql 语句限制的最大值,那么性能真的好吗?

博主疯狂谷歌百度,都没有找到有人来具体的说一下这个问题,不过在高性能 mysql 里面发现一句话:

客户端用一个单独的数据包将查询请求发送给服务器,所以当查询语句很长的时候,需要设置 max_allowed_packet 参数。但是需要注意的是,如果查询实在是太大,服务端会拒绝接收更多数据并抛出异常。与之相反的是,服务器响应给用户的数据通常会很多,由多个数据包组成。但是当服务器响应客户端请求时,客户端必须完整的接收整个返回结果,而不能简单的只取前面几条结果,然后让服务器停止发送。因而在实际开发中,尽量保持查询简单且只返回必需的数据,减小通信间数据包的大小和数量是一个非常好的习惯,这也是查询中尽量避免使用 SELECT *以及加上 LIMIT 限制的原因之一。

后面通过各种百度,博主觉得最大只是代表传输数据包的最大长度,但性能是不是最佳就要从各个方面来分析了。比如下面列出的插入缓冲,以及插入索引时对于缓冲区的剩余空间需求,以及事务占有的内存等,都会影响批量插入的性能。

四、其他影响插入性能的因素

1、首先是插入的时候,要注意缓冲区的大小使用情况

在分析源码的过程中,有一句话:如果 buffer pool 余量不足 25%,插入失败,返回 DB_LOCK_TABLE_FULL。这个错误并不是直接报错:max_allowed_packet 不够大之类的,这个错误是因为对于 innodb 引擎来说,一次插入是涉及到事务和锁的,在插入索引的时候,要判断缓冲区的剩余情况,所以插入并不能仅仅只考虑 max_allowed_packet 的问题,也要考虑到缓冲区的大小。

2、插入缓存

另外对于 innodb 引擎来说,因为存在插入缓存(Insert Buffer)这个概念,所以在插入的时候也是要耗费一定的缓冲池内存的。当写密集的情况下,插入缓冲会占用过多的缓冲池内存,默认最大可以占用到 1/2 的缓冲池内存,当插入缓冲占用太多缓冲池内存的情况下,会影响到其他的操作。

也就是说,插入缓冲受到缓冲池大小的影响,缓冲池大小为:

mysql> show variables like "innodb_buffer_pool_size";

+-------------------------+-----------+

| Variable_name | Value |

+-------------------------+-----------+

| innodb_buffer_pool_size | 134217728 |

+-------------------------+-----------+

换算后的结果为:128M,也就是说,插入缓存最多可以占用 64M 的缓冲区大小。这个大小要超过咱们设置的 sql 语句大小,所以可以忽略不计。

详细解释:

我们都知道,在 InnoDB 引擎上进行插入操作时,一般需要按照主键顺序进行插入,这样才能获得较高的插入性能。当一张表中存在非聚簇的且不唯一的索引时,在插入时,数据页的存放还是按照主键进行顺序存放,但是对于非聚簇索引叶节点的插入不再是顺序的了,这时就需要离散的访问非聚簇索引页,由于随机读取的存在导致插入操作性能下降。

InnoDB 为此设计了 Insert Buffer 来进行插入优化。对于非聚簇索引的插入或者更新操作,不是每一次都直接插入到索引页中,而是先判断插入的非聚集索引是否在缓冲池中,若在,则直接插入;若不在,则先放入到一个 Insert Buffer 中。

看似数据库这个非聚集的索引已经查到叶节点,而实际没有,这时存放在另外一个位置。然后再以一定的频率和情况进行 Insert Buffer 和非聚簇索引页子节点的合并操作。这时通常能够将多个插入合并到一个操作中,这样就大大提高了对于非聚簇索引的插入性能。

3、使用事务提升效率

还有一种说法,使用事务可以提高数据的插入效率,这是因为进行一个 INSERT 操作时,MySQL 内部会建立一个事务,在事务内才进行真正插入处理操作。通过使用事务可以减少创建事务的消耗,所有插入都在执行后才进行提交操作。大概如下:

START TRANSACTION;

INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)

VALUES ("0", "userid_0", "content_0", 0);

INSERT INTO `insert_table` (`datetime`, `uid`, `content`, `type`)

VALUES ("1", "userid_1", "content_1", 1);

...

COMMIT;

事务需要控制大小,事务太大可能会影响执行的效率。MySQL 有 innodb_log_buffer_size 配置项,超过这个值会把 innodb 的数据刷到磁盘中,这时,效率会有所下降。所以比较好的做法是,在数据达到这个这个值前进行事务提交。

查看:show variables like "%innodb_log_buffer_size%";

+------------------------+----------+

| Variable_name | Value |

+------------------------+----------+

| innodb_log_buffer_size | 67108864 |

+------------------------+----------+

大概是:64M

这种写法和批量写入的效果差不多,只不过 sql 语句还是单句的,然后统一提交。一个瓶颈是 SQL 语句的大小,一个瓶颈是事务的大小。当我们在提交 sql 的时候,首先是受到 sql 大小的限制,其次是受到事务大小的限制。在开启事务的情况下使用批量插入,会节省不少事务的开销,如果要追求极致的速度的话,建议是开着事务插入的。

不过需要注意一下,内存是有限且共享的,如果批量插入占用太多的事务内存,那么势必会对其他的业务操作等有一定的影响。

4、通过配置提升读写性能

也可以通过增大 innodb_buffer_pool_size 缓冲区来提升读写性能,只是缓冲区是要占用内存空间的,内存很珍贵,所以这个方案在内存富裕,而性能瓶颈的时候,可以考虑下。

5、索引影响插入性能

如果表中存在多个字段索引,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护。这样就降低了数据的插入速度。对于普通的数据表,主键索引是肯定要有的,想要加快性能的话,就是要有序插入,每次插入记录都在索引的最后面,索引的定位效率很高,并且对索引调整较小。如果插入的记录在索引中间,需要 B+tree 进行分裂合并等处理,会消耗比较多计算资源,并且插入记录的索引定位效率会下降,数据量较大时会有频繁的磁盘操作。

五、总结

博主经过测试+谷歌,最终是选用的一次批量插入数据量为 max_allowed_packet 大小的一半。只是在不断的搜索中,发现影响插入性能的地方挺多的,如果仅仅是拿 max_allowed_packet 这个参数作为分析,其实是没有意义的,这个参数只是设置最大值,但并不是最佳性能。

不过需要注意,由于 sql 语句比较大,所以才执行完插入操作之后,一定要释放变量,不要造成无谓的内存损耗,影响程序性能。

对于我们的 mysql 来说也是一样的,mysql 的最佳性能是建立在各个参数的合理设置上,这样协同干活儿的效果最佳。如果其他设置不到位的话,就像是木桶原理一样,哪怕内存缓冲区设置的很大,但是性能取决的反而是设置最差的那个配置。关于 mysql 的配置调优,我们都在路上,加油!

小伙伴们有兴趣想了解内容和更多相关学习资料的请点赞收藏+评论转发+关注我,后面会有很多干货。

java 培训 MySQL 一次性插入多行数据的操作

原文出处作者:零度

相关内容

【联线智慧法院】内蒙古自治区高级人民法院举办第十四期政法大数据平台与规范量刑智能辅助系统培训

为全面贯彻落实2023年全区政法工作重点任务,进一步提升全区法院应用政法大数据智能化应用平台的能力和水平,10月20日,自治区高院针对全区政法大数据平台及规范量刑智能辅助系统的使用开展全面系统的实操培训。自治区高院党组副书记、副院长王旭军,···

贵州省生态环境厅电子政务中心举办2023年全省生态环境网络安全培训班

10月12日至13日,贵州省生态环境厅电子政务中心举办了2023年全省生态环境网络安全培训班,厅直属各单位和各市(州)生态环境局信息技术负责人现场参训,各区(县)生态环境分局通过视频会议参训。本次培训班强调,贵州省生态环境厅电子政务中心作为···

提升网络建设水平 海南举办2023年电子政务网络安全专题培训

新海南客户端、南海网、南国都市报5月19日消息(记者 姚皓)5月19日,海南2023年电子政务网络安全专题培训在澄迈举行,活动旨在加快推进海南省网络安全建设,加强全省党政机关单位网络安全防护水平,为海南自贸港、数字政府建设创造安全、有序、稳···

格尔木市气象局举办2023年网络安全培训班

10月27日,格尔木市气象局举办网络安全知识培训班,进一步加强网络安全宣传教育,营造安全、健康、文明、和谐的网络环境。格尔木市气象局全体干部职工通过线上或线下方式参加了此次培训。培训围绕网络安全、数据安全等方面展开,解读了当前国内外网络安全···

2023年黑龙江省网络安全宣贯培训会在哈尔滨召开

为贯彻落实中央网信办、公安部相关工作要求,推动党委(党组)网络安全工作责任制和关键信息基础设施安全保护制度深入落实,7月18日,由省委网信办、省公安厅联合举办的2023年黑龙江省网络安全专题培训暨《关键信息基础设施安全保护要求》国家标准宣贯···

京湾区数学建模与人工智能培训在澳门举办

8月25至26日,国家人工智能推广暨京湾区数学建模与人工智能培训在澳门培正中学及康桥教育中心举行。图为部分出席者25日在澳门培正中学合影。 钟欣 摄中新网澳门8月26日电 国家人工智能推广暨京湾区数学建模与人工智能培训25日至26日在澳门培···

淘宝大学参与香港KOL培训 赋能香港青年就业创业

中新社香港3月16日电 (记者 史冰筠)香港青年电商促进会16日宣布,将同阿里巴巴旗下培训平台淘宝大学联合举办淘宝主播培训班,聘请淘宝大学专业的直播导师进行授课,希望赋能学员通过电商拓宽就业、创业渠道,带动香港电商发展。香港青年电商促进会在···

调查:近半香港企业开展新科技培训 涵盖大数据等

中新网6月25日电 据香港《文汇报》报道,香港的一项调查发现,46%受访企业于过去2年间,已开展和新科技有关的雇员培训,内容涵盖大数据、云端技术、物联网及人工智能等。香港人力资源管理学会公布香港培训调查报告。图片来源:香港《文汇报》/赵梦萦···

港媒:近半香港企业开展新科技培训 涵盖大数据等

据香港《文汇报》报道,香港的一项调查发现,46%受访企业于过去2年间,已开展和新科技有关的雇员培训,内容涵盖大数据、云端技术、物联网及人工智能等。香港人力资源管理学会公布香港培训调查报告。图片来源:香港《文汇报》/赵梦萦 摄香港人力资源管理···

自治区司法厅举办全区司法行政系统网络安全和信息化建设工作能力提升培训班

为深入学习贯彻党的二十大精神和习近平新时代中国特色社会主义思想,贯彻落实习近平总书记对网络安全和信息化工作的重要指示和全国网络安全和信息化工作会议精神,推动全区司法行政系统网络安全和信息化建设工作高质量发展,9月19日—20日自治区司法厅组···

2021年甘肃省网络安全管理员培训班在兰开班

中国甘肃网12月27日讯(本网记者 李红军 任磊)今天上午,由甘肃省委网信办主办、兰州大学国家大学科技园承办的2021年甘肃省网络安全管理员培训班在兰州开班。省委网信办副主任刘宗礼出席开班仪式并作动员讲话,兰州大学网信办主任、信息科学与工程···

数据库使用方法系列培训活动之二|台湾月旦知识库线上讲座

会议主题:西北政法大学【月旦知识库】教育训练会议时间:2022/01/18 15:30-17:30 (GMT+08:00) 中国标准时间 - 北京点击链接入会,或添加至会议列表:https://meeting.tencent.com/dm/···

2023年1 X大数据平台运维证书省级师资培训在河南开放大学举办

7月13日上午,2023年1+X“大数据平台运维证书”省级师资培训在河南开放大学(郑州信息科技职业学院)开班,此次培训由河南省教育厅主办,郑州信息科技职业学院承办。河南开放大学(郑州信息科技职业学院)副校长李小明、培训学院院长张颖、信息工程···

【国家网络安全宣传周】福安市开展网络安全培训

为进一步提升网络安全管理工作水平,增强广大干部网络安全风险防范能力,9月12日下午,福安市开展网络安全培训,福安市各乡镇(街道)、市直单位网络安全业务人员90余人参加培训。本次培训邀请了奇安信福建分区网络安全技术人员郑泽辉进行授课。现场培训···

花溪区开展教育系统网络安全培训

7月4日,由花溪区委网信办指导,区教育局主办的花溪教育系统数据安全培训在溪南高中举行,全区公民办中小学、幼儿园、中职学校相关人员300余人参训。培训邀请网络工程师对数据安全文件进行解读,并通过真实案例介绍了数据安全的问题及处置方法以及数据安···

2023年广西招商引资大数据平台(二期)专题培训会在邕召开

8月24日,2023年广西招商引资大数据平台(二期)专题培训会在南宁召开。培训会邀请大数据招商专家对平台新增功能及使用操作进行讲解,并介绍近年招商工作趋势和产业发展特点,分享大数据招商工作经验和典型案例。全区各市、县区、园区招商业务骨干和自···

云南粉笔:依托大数据智能分析打造公考培训新标准

2023年9月2日,云南粉笔在昆明举行了盛大的省考产品发布会,吸引了来自全国各地的教育专家、媒体代表以及公考学子齐聚一堂。本次发布会上,粉笔推出最新研发的省考培训产品,将线上与线下课堂相结合,依托大数据智能分析,打造公考培训新标准。 云南粉···

2023年度室内设计1 X证书师资及考评员培训(黑龙江站)成功举办

2023年8月21日-25日,为提升试点院校“室内设计职业技能等级证书”教育培训质量,积极推动2023年度证书试点工作顺利开展,由中国室内装饰协会主办、哈尔滨职业技术学院承办、黑龙江省室内装饰协会协办的“2023年度全国室内设计职业技能等级···

昆明经开区开展2023年春漫社区老年人智能手机使用暨网络安全培训活动

来源:【昆明日报-掌上春城】掌上春城讯 “五社联动送服务,点亮民生微幸福”。8月17日,昆明经济技术开发区青年志愿者协会党支部在春漫社区组织开展“融入智能e时代 健康银龄新生活”老年人智能手机使用暨网络安全培训活动。本次培训活动围绕老年人日···

2023年全省“十四五”全民健康信息化与网络安全培训班举办

5月11日—12日,2023年全省“十四五”全民健康信息化与网络安全培训班在张家口市举办。省卫生健康委二级巡视员范素文出席会议并讲话。培训班总结了2022年网络安全和信息化工作,安排了2023年重点工作。培训班邀请国家和省内有关专家对卫生健···