2

我正在尝试将大约 5 亿行垃圾数据插入数据库进行测试。现在我有一个 PHP 脚本循环遍历一个SELECT/INSERT内部的几个语句TRANSACTION ——显然这不是最好的解决方案。这些表是 InnoDB(行级锁定)。

我想知道我是否(正确)分叉了这个过程,这会加快这个INSERT过程吗?按照目前的速度,完成需要 140 个小时。我担心两件事:

  1. 如果INSERT语句必须获得写锁,那么它是否会使分叉变得无用,因为多个进程不能同时写入同一个表?

  2. 我正在使用SELECT...LAST_INSERT_ID()(在 a 内TRANSACTION)。当多个进程INSERT进入数据库时​​,这个逻辑会中断吗?我可以为每个分叉创建一个新的数据库连接,所以我希望这可以避免这个问题。

  3. 我应该使用多少个进程?查询本身很简单,我有一个普通的双核开发盒,有 2GB 内存。我将我的 InnoDB 设置为使用 8 个线程 ( innodb_thread_concurrency=8),但我不确定我是否应该使用 8 个进程,或者这是否是考虑匹配的正确方法。

谢谢你的帮助!

4

2 回答 2

7

MySQL 文档讨论了有效插入大量记录。似乎明显的赢家是使用LOAD DATA INFILE命令,然后是插入多个值列表的插入。

于 2009-09-02T03:44:56.087 回答
4

1)是的,会有锁争用,但是innodb被设计用来处理多个线程试图插入。当然,它们不会同时插入,但它会为您处理序列化插入。只需确保您专门关闭交易并尽快完成。这将确保您获得最佳的插入性能。

2) 不,如果每个线程有 1 个连接,则此逻辑不会中断,因为 last_insert_id() 是特定于连接的。

3)这是您只需要进行基准测试即可弄清楚的事情之一。实际上,我会让程序自我调整。使用 8 个线程运行 100 次插入并记录执行时间。然后用一半和两倍的数量再试一次。无论哪个更快,然后围绕该数字对更多线程计数值进行基准测试。

一般来说,你应该总是继续对这类东西进行基准测试,看看哪个更快。在你思考和写出来的时间里,你可能已经有了初步的数字。

于 2009-09-02T03:42:25.297 回答