我试图优化我的代码插入数据到MySQL的一部分。我应该链插入,使一个巨大的多行插入或多个单独的插入更快?


当前回答

当涉及到插入时,Mysql和MariaDB的优化是多么糟糕,这是荒谬的。 我测试了mysql 5.7和mariadb 10.3,没有真正的区别。

我已经在一台带有NVME磁盘、70000 IOPS、1.1 GB/sec seq吞吐量的服务器上进行了测试,这可能是全双工(读和写)。 该服务器也是高性能服务器。 给了它20gb的内存。 数据库完全为空。

在做多行插入时,我收到的速度是每秒5000个插入(尝试了1MB到10MB的数据块)

现在是线索: 如果我添加另一个线程并插入到相同的表中,我突然有2x5000 /秒。 再多一个线程,我就有15000个线程了

考虑一下:当执行一个线程插入时,这意味着您可以按顺序写入磁盘(索引除外)。 当使用线程时,你实际上降低了可能的性能,因为它现在需要做更多的随机访问。 但事实证明,mysql的优化非常糟糕,线程的帮助很大。

这种服务器的实际性能可能是每秒数百万,CPU空闲,磁盘空闲。 原因很明显,mariadb和mysql一样有内部延迟。

其他回答

你可能想:

检查自动提交是否关闭 打开连接 在一个事务中发送多批插入(大约4000-10000行?你看到) 紧密联系

这取决于你的服务器的扩展能力(PostgreSQl, Oracle和MSSQL绝对没问题),用多线程和多连接来做上面的事情。

我只是做了一个小的基准测试,似乎对于很多行它不是更快。这里是我插入28000行的结果:

比10000:164.96秒 到5000分37秒 到1000时:12.56秒 到600秒:12.59秒 比500:13.81秒 到250秒:17.96秒 到400时:14.75秒 差100分27秒

看来1000 * 1000是最好的选择。

MYSQL 5.5 一条sql insert语句需要300到450毫秒。 而下面的stats是内联多个insert语句。

(25492 row(s) affected)
Execution Time : 00:00:03:343
Transfer Time  : 00:00:00:000
Total Time     : 00:00:03:343

我想说内联是一种方式:)

在同一时间通过导线发送尽可能多的插入。实际的插入速度应该是相同的,但是您将从网络开销的减少中看到性能的提高。

多次插入更快,但它有线程。另一个危险是禁用约束检查临时使插入快得多。你的桌子有没有它并不重要。例如,测试禁用外键,享受速度:

SET FOREIGN_KEY_CHECKS=0;

当然,你应该在插入后重新打开它:

SET FOREIGN_KEY_CHECKS=1;

这是插入大数据的常用方法。 数据完整性可能会被破坏,所以在禁用外键检查之前应该注意这一点。