我有大量 CSV 数据集(10M+ 行)需要处理。我还有另外两个文件需要在输出时引用,它们包含的数据放大了我们对 CSV 文件中数百万行的了解。目标是输出一个新的 CSV 文件,其中每条记录都与其他文件中的附加信息合并。
想象一下,大型 CSV 文件包含交易,但客户信息和账单信息记录在另外两个文件中,我们希望输出一个新的 CSV,其中每笔交易都链接到客户 ID 和帐户 ID 等。
一位同事有一个用 Java 编写的函数程序来执行此操作,但速度非常慢。原因是,数百万行的 CSV 文件显然必须被遍历很多很多很多次。
我的问题是——是的,我正在解决这个问题——我应该如何在 Ruby 中解决这个问题?目标是让它更快(现在 18 小时以上,CPU 活动很少)
我可以将这么多记录加载到内存中吗?如果是这样,我该怎么办?
我知道这有点模糊。只是寻找想法,因为这对我来说有点新鲜。
这是我编写的一些用于处理大型 csv 文件(在我的情况下约为 180mb)的 ruby 代码。
https://gist.github.com/1323865 https://gist.github.com/1323865
标准的 FasterCSV.parse 将其全部拉入内存需要一个多小时。这样就把时间缩短到了 10 分钟左右。
相关部分是这样的:
lines = []
IO.foreach('/tmp/zendesk_tickets.csv') do |line|
lines << line
if lines.size >= 1000
lines = FasterCSV.parse(lines.join) rescue next
store lines
lines = []
end
end
store lines
IO.foreach 不会将整个文件加载到内存中,而只是使用缓冲区逐步遍历它。当达到 1000 行时,它会尝试解析 csv 并仅插入这些行。一个棘手的部分是“下一步救援”。如果您的 CSV 包含一些跨多行的字段,您可能需要多获取几行才能获取有效的可解析 csv 字符串。否则,您所在的线路可能位于田野的中间。
在要点中,您可以看到另一个很好的优化,它使用 MySQL 的更新ON DUPLICATE KEY
。这允许您批量插入,如果检测到重复键,它只会覆盖该行中的值,而不是插入新行。您可以将其视为一个查询中的创建/更新。您需要在至少一列上设置唯一索引才能使其正常工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)