MySQL顺序插入很慢,而线程插入很快 - 为什么?

标签 mysql performance go goroutine

我发现与插入相同行数的多线程解决方案相比,按顺序将数据插入我的数据库非常慢。
在我的顺序方法中插入 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)
                }
            }
        }()
}

为什么第一个版本比第二个版本慢?
有任何想法吗?我是否使用了错误的函数来插入数据?

最佳答案

运行 INSERT 有很多开销。 :

  • 客户端和服务器之间的通信。
  • 解析INSERT
  • 开 table 等
  • 获取下一个 AUTO_INCREMENT值(value)。
  • 检查冲突、死锁等
  • 提交事务。

  • 所有这些都在单个 CPU 中完成,如有必要,还需要等待 I/O。

    你有 50 个线程;他们跑得快了 24 倍。

    但你可以做到 10 倍——将行批量为单个 INSERT一次 100 行。这消除了大部分开销,尤其是提交。 (超过 100-1000 行会导致 yield 递减和其他开销;所以停在那里。)

    同时,使用的线程数不要超过你所拥有的 CPU 内核数的两倍。否则,他们只会相互绊倒。这可能就是为什么 50 个线程的速度只有 24 倍。

    关于MySQL顺序插入很慢,而线程插入很快 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59305917/

    相关文章:

    go - 我应该如何根据 URL 切换

    arrays - Golang - 结构、初始化和 memcpy - 什么是正确的方法?

    html - 处理 CORS 表单提交

    java - 使用 OpenJDK 8 时为 "No negotiable cipher suite",但在使用 Oracle Java 8 时不是

    php - 需要从多个具有动态用户 ID 的表插入产品表

    mysql - 优化 SELECT COUNT(DISTINCT(col)) var, col2 var2 FROM table WHERE col< >'X' and col2 between 'Y' and 'Z' GROUP BY var2 ORDER BY var DESC;为了速度?

    c++ - GetDC ReleaseDC 特定上下文中的高 CPU 使用率

    php - 根据另一列的不同值对 sql 值求和并将结果放入数组中

    sql - 如何在多个表中强制执行唯一性

    asp.net-mvc - 在 MVC3 页面中包含 RenderPartial 的开销是多少