我正在使用spout来读取一个excel文件,其中包含超过500000条记录(每个记录有7列,没有太多的信息)。问题是我的剧本已经过时了。我试着上传这个限制,它变得更好了,但到目前为止,我不能做一个完整的插入,只是在50000行左右的部分插入。这不是我的选择。有没有办法在代码上拆分这个excel文件?我看到的是,即使文件没有插入到数据库中,对它的操作也已经很慢并且超时了。所以。。。有什么建议吗?谢谢!
fdx2calv1#
不管怎样,读取一个有3500000个单元格的文件都不会很快。如果在功能强大的硬件上运行并且excel文件使用内联字符串,则至少需要一分钟。以下是您的选择:如果控制正在读取的excel文件的创建,请确保它使用内联字符串(如果使用spout,这是默认行为)。这将大大加快阅读速度。你提到的慢,即使你只看前2行是由于这一点。当不使用内联字符串时,spout需要首先预处理包含单元格值的文件,因为它们在另一个地方被引用。对于内联字符串,spout可以跳过这一昂贵的步骤,进行真正的流式处理。增加时间限制设置,为脚本留出更多时间来完成其处理(设置\u时间\u限制)批量插入数据库:不要一行一行地插入,而应该1000乘1000(或更多)地插入。每个到db的连接都需要一些时间,因此限制它们是个好主意。拆分文件可能会起作用,但需要提前完成(不是在同一个脚本中,否则只会增加总处理时间…)。希望有帮助!
v2g6jxz62#
你可以试着打电话 set_time_limit() 重复,例如在插入的每一行之后。每次你打电话时它都会重置时间限制。但是,如果服务器管理员设置了全局时间限制,则不允许您超过该限制。但是在mysql中,将50万行逐个插入innodb表本身就很慢,因为它需要在每一行之后进行自动提交。如果你分批插入,你会获得很多速度。例如,您现在可能正在执行以下操作:
set_time_limit()
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'; .当然,这个程序要复杂一点,但要快得多。
SHOW VARIABLES LIKE 'max_allowed_packet';
2条答案
按热度按时间fdx2calv1#
不管怎样,读取一个有3500000个单元格的文件都不会很快。如果在功能强大的硬件上运行并且excel文件使用内联字符串,则至少需要一分钟。
以下是您的选择:
如果控制正在读取的excel文件的创建,请确保它使用内联字符串(如果使用spout,这是默认行为)。这将大大加快阅读速度。你提到的慢,即使你只看前2行是由于这一点。当不使用内联字符串时,spout需要首先预处理包含单元格值的文件,因为它们在另一个地方被引用。对于内联字符串,spout可以跳过这一昂贵的步骤,进行真正的流式处理。
增加时间限制设置,为脚本留出更多时间来完成其处理(设置\u时间\u限制)
批量插入数据库:不要一行一行地插入,而应该1000乘1000(或更多)地插入。每个到db的连接都需要一些时间,因此限制它们是个好主意。
拆分文件可能会起作用,但需要提前完成(不是在同一个脚本中,否则只会增加总处理时间…)。
希望有帮助!
v2g6jxz62#
你可以试着打电话
set_time_limit()
重复,例如在插入的每一行之后。每次你打电话时它都会重置时间限制。但是,如果服务器管理员设置了全局时间限制,则不允许您超过该限制。但是在mysql中,将50万行逐个插入innodb表本身就很慢,因为它需要在每一行之后进行自动提交。
如果你分批插入,你会获得很多速度。例如,您现在可能正在执行以下操作:
而是这样做:
这样一来,mysql上每五行的提交开销就会增加,而不是每一行的提交开销。请注意,您可以在一个insert中放入许多行,而不仅仅是五行。mysql对查询长度的唯一限制是
SHOW VARIABLES LIKE 'max_allowed_packet';
.当然,这个程序要复杂一点,但要快得多。