优化MySQL插入以处理数据流

优化MySQL插入以处理数据流,mysql,optimization,bulkinsert,Mysql,Optimization,Bulkinsert,我正在使用高速数据流,并执行以下步骤将数据存储到MySQL数据库中。对于每个新到达的项目 (1) 解析传入项 (2) 执行几个“重复密钥更新时插入…” 我曾经消除了一次额外的数据库往返 在尝试提高整体性能的同时,我考虑了以下方式进行批量更新: (1) 解析传入项 (2) 生成带有“INSERT…ON DUPLICATE KEY UPDATE”的SQL语句并附加到文件中 定期将文件中的SQL语句刷新到数据库中 两个问题: (1) 这会对数据库负载产生积极影响吗 (2) 我应该如何将语句刷

我正在使用高速数据流,并执行以下步骤将数据存储到MySQL数据库中。对于每个新到达的项目

  • (1) 解析传入项
  • (2) 执行几个“重复密钥更新时插入…”
我曾经消除了一次额外的数据库往返

在尝试提高整体性能的同时,我考虑了以下方式进行批量更新:

  • (1) 解析传入项
  • (2) 生成带有“INSERT…ON DUPLICATE KEY UPDATE”的SQL语句并附加到文件中
定期将文件中的SQL语句刷新到数据库中

两个问题:

  • (1) 这会对数据库负载产生积极影响吗
  • (2) 我应该如何将语句刷新到数据库中,以便索引仅在完成刷新后重建?(使用事务?)
更新:我正在使用perldbi+MySQL-MyISAM


提前感谢您的评论。

您没有说您运行的是哪种数据库访问环境(PERL DBI?JDBC?ODBC?),或者您使用的是哪种表存储引擎(MyISAM?InnoDB?)

首先,您选择INSERT是正确的。。。在重复密钥更新时。好的移动,除非你能保证唯一的键

其次,如果您的数据库访问环境允许,您应该使用准备好的语句。如果您将一组语句写入一个文件,然后让数据库客户机再次读取该文件,那么您肯定不会获得良好的性能。直接从使用传入数据流的软件包执行插入操作

第三,选择合适的表存储引擎。MyISAM插入将比InnoDB更快,因此如果您记录数据并稍后检索数据,这将是一个胜利。但InnoDB具有更好的事务完整性。如果你真的处理数据吨位,并且你不需要经常阅读它,考虑存档存储引擎。

最后,考虑在一批插入的开始处执行一个开始事务。命令,然后在固定行数(如100行左右)后执行提交和另一个启动事务。如果您使用InnoDB,这将大大加快速度。如果您使用的是MyISAM或ARCHIVE,这并不重要


您的大赢家将来自准备好的语句和存储引擎的最佳选择。

如果您的数据不需要立即进入数据库,您可以将插入数据缓存到某个位置,然后发出一个更大的插入语句,例如

在表_中插入名称(x,y,z)值(x1,y1,z1),(x2,y2,z2)。。。(xN,yN,zN)在重复更新中

为了清楚起见,我将保留一个待处理插入的列表。在本例中,是(x,z,y)三联体的列表。然后,一旦列表超过某个阈值(N),就生成insert语句并发出它

我没有为您提供准确的计时数据,但是与单独插入每一行相比,这提高了大约10倍的性能

我也没有使用N的值,但是我发现1000可以很好地工作。我希望最佳值受硬件和数据库设置的影响


希望这有帮助(我也在使用MyIsam)。

谢谢。我已经更新了原始帖子,表明我正在MyISAM存储引擎中使用Perl DBI。我的目标之一是加快对传入项的初始处理,因为我们由于速度缓慢而丢失了其中的一些项。只是澄清一下-您说对MyISAM表使用事务是不相关的?因此,在这种情况下,没有任何技术可以加速数百万项的批量插入?正确。MyISAM不提供事务锁定或完整性。但结果是速度更快。任何人都可以在准备好的语句上展开,而不是从文件中展开。该手册指出,“从文本文件加载表时,使用LOAD DATA INFILE。这通常比使用INSERT语句快20倍。”当然,您必须先写入文件……文件必须位于mysqld进程可以访问的文件系统上(也就是说,它必须位于mysqld服务器可用的文件系统中)。如果这是真的,效果会很好。我也认为这个方法比上面的答案好。