每天,我会得到一个包含25万行40列的csv源文件。 290MB。我将需要对其进行过滤,因为它的行数超过了我的需要,列数也超过了我的需要。
对于每个符合过滤条件的行,我们希望使用其PHP API一次将其更新到目标系统1记录中。
在获得最快性能的API调用(读取/过滤/加载)之前,什么是最好的方法?
遍历文件的每一行,确定它是否是我想要的行,仅获取我需要的列,然后将其传递给API?
使用LOAD DATA INFILE将所有记录加载到临时MySQL表中。然后在表中查询所需的行和字段,并遍历结果集以将每条记录传递给API?
还有更好的选择吗?
谢谢!
答案 0 :(得分:0)
我首先需要做一个假设,大部分25万行将进入数据库。如果百分比很小,那么遍历文件并批量发送所有行肯定会更快。
不同的配置可能会影响这两种方法,但是一般而言,第二种方法的执行效果更好,而脚本编写工作却更少。
方法1:最坏的情况是将每一行发送到服务器。更多往返和更多小的提交。
您可以在此处进行改进的是批量发送行,也许一起发送几百行。您会看到更好的结果。
方法2:由于ACID的所有开销和复杂性,MyISAM将比InnoDB更快。如果您可以接受MyISAM,请先尝试。
对于InnoDB,有一个更好的方法3(实际上是方法1和方法2的混合)。 由于InnoDB不会进行表锁定,因此您可以尝试同时导入多个文件,即将CSV文件分离为多个文件并从脚本中执行加载数据。不要先将auto_increment键添加到表中,以避免auto_inc锁定。
答案 1 :(得分:0)
LOAD DATA
,但对不需要保留的列说@dummy1, @dummy2
等。这样就消除了多余的列。加载到临时表中。 (1条SQL语句。)INSERT INTO real_table SELECT ... FROM tmp_table WHERE ...
来过滤掉不必要的行并将所需的行复制到真实表中。 (1条SQL语句。)您没有提到步骤2的任何需要。您可能需要一些注意事项:
在一个项目中,我做了:
INSERT INTO summary SELECT a,b,COUNT(*),SUM(c) FROM tmp GROUP BY a,b;
。或使用INSERT ON DUPLICATE KEY UPDATE
处理summary
中已经存在的行。是否使用MyISAM,InnoDB或MEMORY-您需要对自己的案例进行基准测试。由于每个处理步骤都会进行全表扫描,因此tmp表上不需要索引。
因此,每24小时0.3GB-应该不流汗。