MySQL 批量操作,一次插入多少行数据效率最高?(2)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: MySQL 批量操作,一次插入多少行数据效率最高?

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

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的配置调优,我们都在路上,加油!


版权声明:本文为CSDN博主「铁柱同学」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/LJFPHP/article/details/99708888


参考:


参考:mysql技术内幕 Innodb篇

https://www.cnblogs.com/aicro/p/3851434.html

https://my.oschina.net/songhongxu/blog/163063

https://my.oschina.net/anuodog/blog/3002941

http://mysql.taobao.org/monthly/2017/09/10/

https://cloud.tencent.com/developer/article/1200824


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
5月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
3月前
|
SQL 人工智能 关系型数据库
如何实现MySQL百万级数据的查询?
本文探讨了在MySQL中对百万级数据进行排序分页查询的优化策略。面对五百万条数据,传统的浅分页和深分页查询效率较低,尤其深分页因偏移量大导致性能显著下降。通过为排序字段添加索引、使用联合索引、手动回表等方法,有效提升了查询速度。最终建议根据业务需求选择合适方案:浅分页可加单列索引,深分页推荐联合索引或子查询优化,同时结合前端传递最后一条数据ID的方式实现高效翻页。
157 0
|
2月前
|
存储 关系型数据库 MySQL
在CentOS 8.x上安装Percona Xtrabackup工具备份MySQL数据步骤。
以上就是在CentOS8.x上通过Perconaxtabbackup工具对Mysql进行高效率、高可靠性、无锁定影响地实现在线快速全量及增加式数据库资料保存与恢复流程。通过以上流程可以有效地将Mysql相关资料按需求完成定期或不定期地保存与灾难恢复需求。
169 10
|
3月前
|
SQL 存储 缓存
MySQL 如何高效可靠处理持久化数据
本文详细解析了 MySQL 的 SQL 执行流程、crash-safe 机制及性能优化策略。内容涵盖连接器、分析器、优化器、执行器与存储引擎的工作原理,深入探讨 redolog 与 binlog 的两阶段提交机制,并分析日志策略、组提交、脏页刷盘等关键性能优化手段,帮助提升数据库稳定性与执行效率。
|
5月前
|
存储 SQL 缓存
mysql数据引擎有哪些
MySQL 提供了多种存储引擎,每种引擎都有其独特的特点和适用场景。以下是一些常见的 MySQL 存储引擎及其特点:
141 0
|
21天前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
57 3
|
28天前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
2月前
|
存储 运维 关系型数据库
从MySQL到云数据库,数据库迁移真的有必要吗?
本文探讨了企业在业务增长背景下,是否应从 MySQL 迁移至云数据库的决策问题。分析了 MySQL 的优势与瓶颈,对比了云数据库在存储计算分离、自动化运维、多负载支持等方面的优势,并提出判断迁移必要性的五个关键问题及实施路径,帮助企业理性决策并落地迁移方案。
|
15天前
|
关系型数据库 MySQL 分布式数据库
阿里云PolarDB云原生数据库收费价格:MySQL和PostgreSQL详细介绍
阿里云PolarDB兼容MySQL、PostgreSQL及Oracle语法,支持集中式与分布式架构。标准版2核4G年费1116元起,企业版最高性能达4核16G,支持HTAP与多级高可用,广泛应用于金融、政务、互联网等领域,TCO成本降低50%。
|
16天前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。

推荐镜像

更多