Go 语言操作 MySQL 更新数据,使用事务以后耗时反而增加 30 倍

2017-07-21 11:22:29 +08:00
 billion

一开始开了 100 个 goroute,在每个 goroute 里面一条一条更新数据:

for i:=0; i<100;i++{
    go func(chan){
      para1 := <- chan
      stmt, _ := db.Prepare("update.....")
      stmt.Exec(para1)
    }
}

可以做到 2 秒钟更新 1000 条。

后来改用事务来批量更新

for i:=0; i<100;i++{
    go func(chan){
      var paraArray []string
      for para := range chan{
         paraArray = append(paraArray, para)
         if len(paraArray) >= 1000 {
             tx, _ := db.Begin()
             for _, para := range paraArray{
                  tx.Exec("update.....", para) 
             }
              tx.Commit()
             paraArray = paraArray[:0]
          }
        }
    }
}

这样每个事务里面的 1000 条语句,运行时间高达 1 分钟。请问为什么用事务反而导致效率严重降低了?

3700 次点击
所在节点    Go 编程语言
49 条回复
billion
2017-07-21 22:49:30 +08:00
@amghost 数据确实可能有重叠
billion
2017-07-21 22:49:54 +08:00
@specita 我怀疑应该是代码的问题。
alex8
2017-07-21 23:18:16 +08:00
mysql 默认单数据更新语句自动事物,你只发了一条 updae....,Mysql 会自动用 Begin 和 Commit 把你的语句事物化。单个语句加显式事物没什么意义
akira
2017-07-21 23:49:30 +08:00
1. 看看你的 update 是不是导致表锁了.
2. 多条语句合并到一个事务内提交以提高效率 比较适合 用于单会话 导数据
3. 高并发下,事务越短越好。
wdlth
2017-07-22 00:16:18 +08:00
LZ 的 MySQL 用的是 InnoDB 还是 MyISAM 存储引擎?
billion
2017-07-22 07:52:18 +08:00
@wdlth InnoDB
billion
2017-07-22 07:52:34 +08:00
@akira 第三条很重要。
abcbuzhiming
2017-07-22 10:14:20 +08:00
@wdlth MyISAM 没有事务,能开事务必然是 InnoDB
wdlth
2017-07-22 18:14:40 +08:00
@abcbuzhiming MariaDB 的 Aria 也能开事务,不过他没明确说是 MariaDB,那应该还是 InnoDB。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/376931

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX