快速处理大量CSV数据的最佳方式

NJ.*_*NJ. 11 ruby csv

我有需要处理的大型CSV数据集(10M +行).我还有两个需要为输出引用的文件 - 它们包含的数据可以放大我们对CSV文件中数百万行的了解.目标是输出一个新的CSV文件,其中每个记录与其他文件中的附加信息合并.

想象一下,大型CSV文件有交易,但客户信息和账单信息记录在另外两个文件中,我们想要输出一个新的CSV,每个交易都链接到客户ID和账户ID等.

一位同事有一个用Java编写的功能程序来执行此操作,但速度非常慢.原因是具有数百万行的CSV文件显然需要经过许多次,多次.

我的问题是 - 是的,我到了 - 我应该如何在Ruby中处理这个问题?目标是让它更快(现在18小时以上,CPU活动很少)

我可以将这么多记录加载到内存中吗?如果是这样,我该怎么做?

我知道这有点模糊.只是寻找想法,因为这对我来说有点新鲜.

Bri*_*ong 30

这是我编写的一些ruby代码来处理大型csv文件(在我的情况下约为180mb).

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
Run Code Online (Sandbox Code Playgroud)

IO.foreach不会将整个文件加载到内存中,只是使用缓冲区逐步执行它.当它到达1000行时,它会尝试解析csv并只插入那些行.一个棘手的部分是"下一个救援".如果您的CSV有一些跨越多行的字段,您可能需要再获取几行来获取有效的可解析csv字符串.否则,您所在的行可能位于字段的中间.

在要点中,您可以看到另一个使用MySQL更新的优秀优化ON DUPLICATE KEY.这允许您批量插入,如果检测到重复键,它只是覆盖该行中的值而不是插入新行.您可以将其视为一个查询中的创建/更新.您需要在至少一列上设置唯一索引才能使其生效.

  • 那个<1000的最后一组线怎么样? (3认同)

Ran*_*ndy 2

使用数据库怎么样。

将记录塞入表中,然后使用联接查询它们。

导入可能需要一段时间,但数据库引擎将为连接和检索部分进行优化...