我正在使用高速数据流,并执行以下步骤将数据存储在MySQL数据库中。对于每个新到货项目。
我已经使用INSERT ... ON DUPLICATE KEY UPDATE来消除对数据库的一次额外往返。
在尝试提高整体效果时,我考虑过以下方式进行批量更新:
定期将文件中的SQL语句刷新到数据库。
两个问题:
更新:我使用的是Perl DBI + MySQL MyISAM。
提前感谢任何评论。
答案 0 :(得分:3)
如果您的数据不需要立即进入数据库,您可以在某处缓存插入数据,然后发出一个更大的插入语句,例如
在重复更新时插入table_name(x,y,z)值(x1,y1,z1),(x2,y2,z2),...(xN,yN,zN);;
要清楚,我会维护一个待处理插入列表。在这种情况下,(x,z,y)三元组列表。然后,一旦列表超过某个阈值(N),就会生成insert语句并发出它。
我没有准确的计时数据,但与单独插入每行相比,这个性能提高了大约10倍。
我也没有使用N的值,但我发现1000可以很好地工作。我希望最佳值受硬件和数据库设置的影响。
希望这有帮助(我也在使用MyIsam)。
答案 1 :(得分:1)
你没有说你正在运行什么样的数据库访问环境(PERL DBI?JDBC?ODBC?),或者你正在使用什么样的表存储引擎(MyISAM?InnoDB?)。
首先,你选择INSERT ... ON DUPLICATE KEY UPDATE是正确的。好的举动,除非你能保证唯一的钥匙。
其次,如果您的数据库访问环境允许,您应该使用预准备语句。如果将一堆语句写入文件,然后让数据库客户端再次读取该文件,则肯定不会获得良好的性能。直接从消耗传入数据流的软件包执行INSERT操作。
第三,选择合适的表存储引擎。 MyISAM插入将比InnoDB更快,因此如果您正在记录数据并在以后检索它将是一个胜利。但InnoDB具有更好的事务完整性。如果你真的处理吨位数据,并且不需要经常阅读,请考虑使用ARCHIVE存储引擎。
最后,考虑在一批INSERT ...命令的开头执行START TRANSACTION,然后在固定行数(如100左右)之后执行COMMIT和另一个START TRANSACTION。如果您正在使用InnoDB,这将加快速度。如果您使用的是MyISAM或ARCHIVE,则无关紧要。
您的重大胜利将来自准备好的声明内容和存储引擎的最佳选择。