【问题标题】:Optimizing MySQL inserts to handle a data stream优化 MySQL 插入以处理数据流
【发布时间】:2010-12-18 22:48:52
【问题描述】:

我正在使用高速数据流并执行以下步骤将数据存储在 MySQL 数据库中。对于每件新到货。

  • (1) 解析传入项目。
  • (2) 执行多次“INSERT ... ON DUPLICATE KEY UPDATE”

我已使用INSERT ... ON DUPLICATE KEY UPDATE 消除了到数据库的一次额外往返。

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

  • (1) 解析传入项目。
  • (2) 生成带有“INSERT ... ON DUPLICATE KEY UPDATE”的 SQL 语句并附加到文件中。

定期将文件中的 SQL 语句刷新到数据库中。

两个问题:

  • (1) 这会对数据库负载产生积极影响吗?
  • (2) 我应该如何将语句刷新到数据库,以便仅在完全刷新后重建索引? (使用交易?)

更新:我正在使用 Perl DBI + MySQL MyISAM。

提前感谢任何 cmets。

【问题讨论】:

    标签: mysql optimization bulkinsert


    【解决方案1】:

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

    在重复更新时插入 table_name (x, y, z) 值 (x1, y1, z1), (x2, y2, z2), ... (xN, yN, zN) ...;

    为了清楚起见,我会维护一个待处理插入的列表。在这种情况下,是 (x,z,y) 三元组的列表。然后,一旦您的列表超过某个阈值 (N),您就会生成插入语句并发出它。

    我没有准确的时间数据给你,但与单独插入每一行相比,这提高了大约 10 倍的性能。

    我也没有玩过 N 的值,但我发现 1000 可以很好地工作。我预计最佳值会受到硬件和数据库设置的影响。

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

    【讨论】:

    • 我也认为这种方法比上述答案中提到的要好
    【解决方案2】:

    您没有说您正在运行什么样的数据库访问环境(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,那没关系。

    您的重大胜利将来自准备好的语句材料和存储引擎的最佳选择。

    【讨论】:

    • 谢谢。我更新了原始帖子以表明我在 MyISAM 存储引擎中使用 Perl DBI。我的目标之一是加快传入项目的初始处理,因为由于速度慢,我们正在丢失其中一些项目。
    • 只是为了澄清-您说使用带有MyISAM表的事务是无关紧要的?那么,在这种情况下,没有任何技术可以加快批量插入数百万个项目的速度吗?
    • 正确。 MyISAM 不提供事务锁定或完整性。但结果是它更快。
    • 任何人都可以扩展准备好的语句与文件。手册指出“从文本文件加载表时,使用 LOAD DATA INFILE。这通常比使用 INSERT 语句快 20 倍。”当然要先写文件...
    • 该文件需要位于 mysqld 进程可访问的文件系统中(即,它需要位于 mysqld 服务器可用的文件系统中)。如果这是真的,它会工作得很好。
    猜你喜欢
    • 2013-05-22
    • 2012-04-07
    • 1970-01-01
    • 2018-04-08
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 2015-06-09
    相关资源
    最近更新 更多