简体   繁体   English

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

[英]MySQL sequential inserts are slow while threaded inserts are fast - why?

I found that sequentially inserting data into my database is very slow compared to a multi-threaded solution where both insert the same number of rows.我发现与插入相同行数的多线程解决方案相比,将数据按顺序插入我的数据库非常慢。 Inserting 50000 rows took ~4 mins in my sequential approach and only ~10 seconds with the parallel version.在我的顺序方法中插入 50000 行需要大约 4 分钟,而在并行版本中只需要大约 10 秒。

I use the https://github.com/go-sql-driver/mysql driver.我使用https://github.com/go-sql-driver/mysql驱动程序。
For the database, I just took the recent version of XAMPP for windows and use the MySQL database with its standard config.对于数据库,我只使用了最新版本的 XAMPP for windows 并使用 MySQL 数据库及其标准配置。

sequential version:顺序版本:

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)
        }

}

Parallel version:并行版本:

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)
                }
            }
        }()
}

Why is the first one so slow compared to the second version?为什么第一个版本比第二个版本慢?
Any Ideas?有任何想法吗? Am I maybe using the wrong function for inserting data?我是否可能使用错误的函数插入数据?

There is a lot of overhead in running an INSERT :运行INSERT有很多开销:

  • Communication between client and server.客户端和服务器之间的通信。
  • Parse the INSERT解析INSERT
  • Open the table, etc.打开桌子等。
  • Get next AUTO_INCREMENT value.获取下一个AUTO_INCREMENT值。
  • Check for conflicts, deadlocks, etc.检查冲突、死锁等。
  • Commit the transaction.提交交易。

And all of that is done in a single CPU, with waiting for I/O, if necessary.所有这些都在单个 CPU 中完成,并在必要时等待 I/O。

You have 50 threads;您有 50 个线程; they ran 24 times as fast.他们跑得快 24 倍。

But you can do 10 times as good as that -- Batch up the rows into a single INSERT 100 rows at a time.但是你可以做 10 倍的事情——一次将行批处理成单个INSERT 100 行。 This eliminates much of the overhead, especially the commit.这消除了大部分开销,尤其是提交。 (Going past 100-1000 rows is getting into diminishing returns and other overheads; so stop there.) (超过 100-1000 行会导致收益递减和其他开销;所以就此打住。)

Meanwhile, don't use more threads than, say, twice the number of CPU cores you have.同时,不要使用超过 CPU 内核数两倍的线程。 Otherwise, they will just stumble over each other.否则,他们只会互相绊倒。 The may be why 50 threads was only 24 times as fast.可能就是为什么 50 个线程的速度只有24 倍的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM