将大型Excel文件插入数据库

时间:2018-07-24 10:38:52

标签: php mysql excel bulk-load spout

我正在使用Spout来读取一个超过500.000条记录的Excel文件(每条记录有7列,没有太多信息)。

问题在于我的脚本被淘汰了。 我尝试上传此限制,但它会变得更好,但是到目前为止,我无法完整插入,仅部分插入大约50.000行。

这不是我的选择。 除了代码,有什么方法可以拆分此Excel文件? 我看到的是,即使不将其插入数据库中,该文件的处理也已经很慢并且超时。

那么...有什么建议吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

您可以尝试重复调用set_time_limit(),例如在插入每一行之后。每次您调用时,都会重置时间限制。但是,如果您的服务器管理员设置了全局时间限制,则不允许您超过该时间限制。

但是在MySQL的InnoDB表中一个一百万个地插入行本质上很慢,因为它需要在每一行之后进行一次自动提交。

如果分批执行插入操作,将会获得很大的速度。例如,您现在可能正在执行以下操作:

  INSERT INTO table (col1, col2, col3) VALUES (1, 'baker', 'charlie');
  INSERT INTO table (col1, col2, col3) VALUES (2, 'delta', 'echo');
  INSERT INTO table (col1, col2, col3) VALUES (3, 'foxtrot', 'golf');
  INSERT INTO table (col1, col2, col3) VALUES (4, 'hotel', 'india');
  INSERT INTO table (col1, col2, col3) VALUES (5, 'lima', 'mike');

相反,这样做:

  INSERT INTO table (col1, col2, col3) VALUES 
     (1, 'baker', 'charlie'),
     (2, 'delta', 'echo'),
     (3, 'foxtrot', 'golf'),
     (4, 'hotel', 'india'),
     (5, 'lima', 'mike');

那样,您将在MySQL上每五行而不是每一行承担提交开销。请注意,您可以将多个行放入单个INSERT中,而不仅仅是五个。 MySQL的唯一查询长度限制可通过SHOW VARIABLES LIKE 'max_allowed_packet';找到。

当然,编程要稍微复杂一点,但是它的速度很多

答案 1 :(得分:0)

无论如何,读取包含350万个单元的文件都不会很快。如果在功能强大的硬件上运行并且Excel文件使用内联字符串,则至少需要一分钟。

因此,您可以使用以下选项:

  1. 如果您控制正在读取的Excel文件的创建,请确保它使用内联字符串(如果使用Spout,这是默认行为)。这将大大加快阅读速度。即使您只阅读了前两行,您提到的速度仍然很慢。当不使用内联字符串时,Spout需要先对包含单元格值的文件进行预处理,因为它们是在其他位置引用的。使用内联字符串,Spout可以跳过这一昂贵的步骤,并进行真正的流式传输。
  2. 增加时间限制设置,使脚本有更多时间完成其处理(set_time_limit
  3. 批量插入数据库:您应该以1000 x 1000(或更多)的方式插入行,而不是一一插入。与数据库的每个连接都需要一些时间,因此限制它们是一个好主意。

拆分文件可能可以工作,但需要提前完成(不在同一脚本中,否则会增加总处理时间...)。

希望有帮助!