我正在尝试将大约5亿行垃圾数据插入数据库进行测试。现在我有一个PHP脚本循环遍历SELECT/INSERT
内的几个TRANSACTION
语句 - 显然这不是最好的解决方案。这些表是InnoDB(行级锁定)。
我想知道我是否(正确)分叉了这个过程,这会加快INSERT
进程吗?按照它的速度,需要140个小时才能完成。我关心两件事:
如果INSERT
语句必须获取写锁定,那么它会使forking无效,因为多个进程不能同时写入同一个表吗?
我正在使用SELECT...LAST_INSERT_ID()
(在TRANSACTION
内)。当多个进程INSERT
进入数据库时,这种逻辑是否会中断?我可以为每个fork创建一个新的数据库连接,所以我希望这可以避免这个问题。
我应该使用多少个进程?查询本身很简单,我有一个带2GB RAM的常规双核开发盒。我设置我的InnoDB使用8个线程(innodb_thread_concurrency=8
),但我不确定我是否应该使用8个进程,或者这是否是考虑匹配的正确方法。
感谢您的帮助!
答案 0 :(得分:7)
MySQL文档有a discussion有效插入大量记录。似乎明显的赢家是使用LOAD DATA INFILE命令,然后是插入多个值列表的插入。
答案 1 :(得分:4)
1)是的,会有锁争用,但innodb旨在处理多个尝试插入的线程。当然,它们不会同时插入,但它会为您处理插入序列化。只是确保你专门关闭你的交易,你尽快完成。这将确保您获得最佳的插入性能。
2)不,如果每个线程有1个连接,这个逻辑不会中断,因为last_insert_id()是特定于连接的。
3)这是你需要进行基准测试才能弄清楚的事情之一。实际上,我会让程序自我调整。运行100个插入8个线程并记录执行时间。然后再尝试一半和两倍多。无论哪一个更快,然后围绕该数字计算更多的线程计数值。
总的来说,你应该总是继续对这类东西进行基准测试,看看哪个更快。在您考虑并编写它的时间量上,您可能已经有了初步数字。