Fork MySQL INSERT INTO(InnoDB)

时间:2009-09-02 03:12:35

标签: mysql multithreading insert fork innodb

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

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

  1. 如果INSERT语句必须获取写锁定,那么它会使forking无效,因为多个进程不能同时写入同一个表吗?

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

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

  4. 感谢您的帮助!

2 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

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

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

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

总的来说,你应该总是继续对这类东西进行基准测试,看看哪个更快。在您考虑并编写它的时间量上,您可能已经有了初步数字。