Mysql批量插入更新如何拆分大事务?

本文探讨了Mysql大事务导致的binlog阈值超出问题,以及由此引发的数据库性能下降和锁冲突。解决方案是通过limit分页拆分大事务,使用while循环遍历数据进行批量操作,以避免回滚日志过大和锁冲突。然而,这种方法可能导致auto_increment值不连续增长,即使在仅更新数据的情况下。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 之前在运行Mysql任务的时候报错:binlog(1610646347 bytes) write threshold exceeded,
  • 问题原因是Mysql任务提交的是个大事务,超出binlog设定阈值,使得系统自动终止事务
  • Mysql中的每条记录在更新的时候都会记录一条回滚操作,同一记录在系统中可存在多个版本,导致Mysql的回滚日志越来越大,不过回滚日志会进行删除,Mysql会删除比较老的回滚日志,如果是大事务的话,一直不提交,相当于系统里有很多老的任务视图无法删数,就导致了binlog溢出,同时,大事务还会造成锁冲突,甚至拖垮数据库

一、解决方案

  • 使用limit分页拆分大事务
  • limit x,y表示从第x行开始往后偏移y行
  • 使用while循环遍历数据量按照偏移量拆分
CREATE  PROCEDURE `split_trans`()
### 实现 MySQL 中高效批量插入 为了提高性能,在处理大批量数据插入操作时,应当尽可能减少与数据库服务器之间的通信次数。通过构建单个 `INSERT` 语句来一次性提交多组值是一种有效的方法。 #### 单次连接执行多个插入命令 利用 C# 进行编程时,可以通过创建一次性的数据库连接并在此期间发送一系列预编译好的 SQL 命令给 MySQL 数据库[^1]: ```csharp using (MySqlConnection conn = new MySqlConnection(MySqlHelper.ConnStr)) { string query = "INSERT INTO table_name(column1, column2) VALUES (@col1,@col2)"; using MySqlCommand cmd = new MySqlCommand(query, conn); { // 添加参数定义 cmd.Parameters.AddWithValue("@col1", MySqlDbType.VarChar); cmd.Parameters.AddWithValue("@col2", MySqlDbType.Int32); try { await conn.OpenAsync(); foreach(var item in itemsToInsert) { ((IDataParameter)cmd.Parameters["@col1"]).Value = item.Property1; ((IDataParameter)cmd.Parameters["@col2"]).Value = item.Property2; await cmd.ExecuteNonQueryAsync(); } } catch(Exception ex) { Console.WriteLine(ex.Message); } } } ``` 需要注意的是上述例子虽然展示了如何在一个事务内重复调用同一个命令对象以达到批量化的效果,但这并不是最优化的方式;因为每次循环都会触发网络往返以及解析过程开销较大。 #### 构建单一的大规模 INSERT 语句 更推荐的做法是在应用程序端先收集好所有的待插入记录,之后再拼接成一个包含所有这些记录的长字符串形式的 `VALUES()` 列表作为整个 `INSERT` 的一部分传送给 MySQL 执行引擎去处理[^2]: ```sql -- 插入500条数据到表名为table_name的数据库表中 INSERT INTO table_name (column1, column2, column3,...) VALUES (value1_1,value1_2,value1_3,...), (value2_1,value2_2,value2_3,...), ... (valueN_1,valueN_2,valueN_3,...); ``` 这种方式减少了客户端和服务端之间交互频度的同时也降低了服务端对于每笔请求单独分析的成本,从而提高了整体效率。 #### 使用 LOAD DATA INFILE 加速导入速度 如果要加载非常庞大的文件或外部源的数据集,则应考虑采用 `LOAD DATA INFILE` 方式来进行快速装载作业[^4]: ```sql LOAD DATA LOCAL INFILE '/path/to/file.csv' INTO TABLE tbl_name FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'; ``` 此方法允许直接从本地磁盘读取 CSV 文件并将其中的内容按照指定分隔符拆分成字段后写入目标表格之中,通常情况下它的吞吐率会远高于常规手段。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱夜来香A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值