【发布时间】:2020-04-05 22:09:45
【问题描述】:
我发现,与插入相同行数的多线程解决方案相比,按顺序将数据插入我的数据库非常慢。 在我的顺序方法中插入 50000 行大约需要 4 分钟,而在并行版本中只需大约 10 秒。
我使用https://github.com/go-sql-driver/mysql 驱动程序。
对于数据库,我刚刚使用了最新版本的 Windows 版 XAMPP,并使用 MySQL 数据库及其标准配置。
连续版本:
for i := 0; i < 50000; i++ {
_, err2 := db.Exec("insert into testtable (num, text1, text2) values (?, ?, ?)", i, "txt1", "txt2")
if err2 != nil {
fmt.Println(err2)
}
}
并行版本:
for i := 0; i < 50; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 1000; j++ {
_, err2 := db.Exec("insert into testtable (num, text1, text2) values (?, ?, ?)", 1, "txt1", "txt2")
if err2 != nil {
fmt.Println(err2)
}
}
}()
}
为什么第一个版本比第二个版本慢?
有任何想法吗?我是否使用了错误的函数来插入数据?
【问题讨论】:
-
@armmie 你在问为什么顺序版本需要大约 4 分钟?或者你在问为什么一般来说并发执行的代码比顺序执行的代码“快”?
-
“MySQL 顺序插入很慢,而线程插入很快 - 为什么?” @armmie 我会问“为什么不呢?”。为什么您希望顺序代码与并行代码执行相同的操作?如果不是为了提供比顺序代码更好的性能,并行代码的目的是什么?
-
我假设数据库无论如何都会按顺序处理对同一个表的插入,因此预计性能不会有差异。这就是我感到惊讶的原因。
-
@armmie 如果
db表示单个连接,则可能是这种情况,但是*sql.DB类型是一个为并发使用而设计的连接池,所以当你的顺序代码,因为它是顺序的,只使用池中的单个连接,并发代码使用 mysql 服务器允许和池可以管理的尽可能多的连接。 -
哦,所以运行时会自动创建更多连接。我认为它只会将并发插入序列化到同一个连接中,因为它们都具有相同的数据库引用。谢谢您的帮助!! :)
标签: mysql performance go goroutine