Go 语言 MySQL Update 200 万条数据的正确姿势是什么?

2017-07-20 16:53:38 +08:00
 billion

根据主键来更新每一条数据。

stmt, err := db.Prepare("update xxx set age=? where primaryid = ?")
panic(err)
_, err2 := stmt.Exec(age, id)

由于主键是唯一的,所以需要一条一条的更新。这种情况下,开了 2000 个 goroute 速度还是非常慢。请问有什么好办法吗?

6222 次点击
所在节点    Go 编程语言
46 条回复
sunchen
2017-07-20 17:01:16 +08:00
大表更新一般选择建新表然后插入合并后的新数据,然后替换老表的方式比较快
caotian
2017-07-20 17:03:18 +08:00
一次拼 N 个 update 语句,一起发给 mysql 试试.
jarlyyn
2017-07-20 17:04:32 +08:00
说实话,这个取决与 mysql 的效率。是否用 go 对效率提升作用不大。
cxbig
2017-07-20 17:07:24 +08:00
可以批量处理的,比方说一次 1 千条数据。
另一个性能上的共识是 INSERT ... ON DUPLICATE KEY UPDATE 速度快过 UPDATE,可以试试
monsterxx03
2017-07-20 17:08:30 +08:00
这个用 goroutine 只会更慢啊,更新主键是有锁的 (gap lock), 你应该把 autocommit 关掉,每个 transaction 更新 1000 条,再 commit, 才 200w, 很快的
mringg
2017-07-20 17:09:48 +08:00
如果 age 上没索引,一会就跑完了
cxbig
2017-07-20 17:10:21 +08:00
另一个点,如果你的表是 InnoDB,那么更新会锁表,Go 这边的并行处理不会直接提升速度
GTim
2017-07-20 17:10:51 +08:00
@monsterxx03 恩,这个可以试一试
gouchaoer
2017-07-20 17:12:25 +08:00
我只想说这种简单的 update 语句 mysql 在 32 核上的性能都是上万 qps 了,区区 200w 数据一个小时内搞定吧
liprais
2017-07-20 17:12:47 +08:00
开一个事务做
gouchaoer
2017-07-20 17:13:28 +08:00
Zzzzzzzzz
2017-07-20 17:16:12 +08:00
这种操作协程 /线程开的越多越慢
billion
2017-07-20 17:23:13 +08:00
@caotian Go 语言拼接 Update 的语句有点麻烦。
billion
2017-07-20 17:26:52 +08:00
@cxbig Go 语言拼接 Update 有点麻烦
billion
2017-07-20 17:27:52 +08:00
@monsterxx03 用 Python 确实可以。但是 GO 语言没有 commit。。。。。
mooncakejs
2017-07-20 17:28:37 +08:00
上事务会快一点, 如果是一次性操作
导出 csv,用 sed 或者程序改,再导入,这样时间可控
fitmewell
2017-07-20 17:28:56 +08:00
@billion 有 commit 仔细看文档
rrfeng
2017-07-20 17:29:21 +08:00
@billion commit 是 MySQL 的概念,跟 go 有什么关系……
utopia5719
2017-07-20 17:35:45 +08:00
@cxbig 你的理解并不对,Innodb 主键更新并不会锁表,innodb 本身就是行锁; insert ... on duplicate 比 update 快的依据是什么?怎么看也不会比 update 快啊,而且 insert on duplicate 这种语句如果真实执行是 update 的话在 binlog 中记录的也是 update 语句,实际执行的也是 update。
honeycomb
2017-07-20 17:38:30 +08:00
@rrfeng
commit 肯定在 go 有对应的封装

随手搜索了一下(关键词: go commit mysql ),看上去里面有你要的
http://studygolang.com/articles/3022

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

https://www.v2ex.com/t/376742

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

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

© 2021 V2EX