0

我有一个数据库,速度不是很快,而且我有一个大约 65000 行的大 CSV。我需要交叉检查这些是否存在,并在需要时更新数据库。

  • 在 CSV 中,有一列包含数据库 ID。它始终是 1:1 的关系。
  • CSV 可能会保存数据库的新输入,因此可能会出现没有数据库条目的情况。
  • 我无法遍历 CSV 并检查每一行,因为它太慢了。
  • 首先从数据库中获取所有结果并将它们存储在每次循环中都是行不通的,因为这会占用大量 RAM。

我该如何执行以下操作:

  • 检查 CSV 中的一行是否有数据库条目。如果是这样,请将其写入另一个 CSV 文件。
  • 如果该行没有数据库条目,则将其写入不同的文件。
  • 将时间跨度保持在 5 分钟以内,最好更短。

CSV 有很多列(例如 70),但我只需要第 5 列来交叉检查 ID。我曾尝试先遍历 CSV 文件,然后用数据库检查它,但这太慢了。可能需要 10 多分钟。我还尝试从数据库中获取所有条目,并循环遍历这些条目。使用循环,运行 CSV(使用 a BufferedStream)并检查它。这确实显着减少了时间(最多 5 分钟),但将无法记录数据库中不存在的条目。

有什么办法可以在保持速度的同时做到这一点?

4

2 回答 2

1

没有足够的信息来给你一个正确的分析,最终得出一个铁定的解决方案。我可以给一些建议。作为记录,包含 65,000 条记录的 CSV 并没有那么大。我也不同意遍历文件太慢,因为我个人曾使用流式阅读器来比较千兆字节大小的文件,这很可能要大一个数量级。

首先,您可以考虑扭转问题。与其在运行 CSV 时拉动数据库,不如考虑将整个集合拉入内存(如果您有一个庞大的数据库,这不是一个好主意,但如果它是可管理的,则可以选择)。如果稍微大一点,您甚至可以将数据库(假设这是单个表或视图(或可能是视图的查询))写入不同的 CSV。这里的核心焦点是让慢速数据库脱离循环。注意:如果这是一个高度事务性的系统,并且您需要“最多一分钟(或 5 分钟)的准确快照”,这可能还不够。我发现这是一个不切实际的期望(即现在的数据仍然代表 5 分钟前,尽管进行了多次编辑)。

接下来,可以考虑减少集合。您的问题中已经提到的一种简单方法是将工作 CSV 从 70 列减少到您需要的 5 列。如果您从数据库中提取相同的数据进行比较,情况也是如此。这只有在加载时间是瓶颈时才有效。根据您的描述,我严重怀疑是这种情况。

您还可以考虑将这两位数据放入内存并在那里计算。非常快。如果由于大小而无法将这两个项目比较到内存中,这将不起作用,这就是为什么过滤到您需要的列是一个有用的练习的原因。

既然您提到了数据库 ID,听起来 CSV 会检查多个数据库。考虑首先按数据库 ID 排序 CSV。如前所述,有些排序算法非常快,应该能够在几秒钟内对 65,000 条记录进行排序。排序的瓶颈通常是内存量和 I/O 速度(主要是磁盘速度)。然后,您可以攻击每个数据库。

正如我在开头所说,我只有足够的信息来提供提示,而不是实际的解决方案,但希望这能激发一些想法。

于 2012-12-10T14:25:41.460 回答
0

迟到的答案,但我已经这样解决了:我将需要的 CSV 列拉到DataTable. 然后我获取我需要检查的所有行(它有一个我可以过滤的特定数字),并遍历这些数据库行。每行都会检查相应的 IDDataTable并将数据放入新的 CSV 中。之后,DataTable 中的行将被删除。最后,我有一个包含确实存在的行并将被导入系统的 CSV,以及一个将导出到包含需要添加的行的 CSV 的 DataTable。

感谢 Gregory 帮助我走上正轨。

于 2012-12-27T08:12:18.073 回答