【问题标题】:C# crosscheck slow database with large CSVC# 交叉检查具有大型 CSV 的慢速数据库
【发布时间】:2012-12-10 14:10:23
【问题描述】:

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

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

我怎样才能做到以下几点:

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

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

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

【问题讨论】:

  • 是什么样的数据库?如果它是一个关系数据库并且数据库上的索引设置正确,那么通过表中的 id 进行选择/更新应该很快。
  • 您对 CSV 有什么控制权?你能删掉出现在数据库中的记录吗?数据库 ID 列是否遵循您可以利用以节省时间的约定?例如你能删掉所有小于你添加到数据库中的最后一个 ID 的 ID 吗?
  • @JohnKoerner 这不是我的数据库,我无法编辑它。它对我来说是只读的。我想索引设置得不是很好,或者根本没有。我必须通过 ODBC 连接器进行连接。
  • @Rawrgramming CSV 是客户端。作为保护,我可以制作副本然后进行编辑,所以是的,我可以完全控制 CSV。虽然行没有排序,但 ID 可能会被打乱。

标签: c# database csv streamreader


【解决方案1】:

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

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

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

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

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

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

【讨论】:

  • 它只有 1 个数据库,如果我不清楚,对不起。数据库应该保存大约相同数量的行,因为文件应该只更新/添加。 65k 或最终 100k 行是否大到可以拉入内存,或者任何计算机都可以处理得很好?
  • 另外,您还需要哪些其他信息才能进行适当的分析?
【解决方案2】:

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

感谢 Gregory 帮助我走上正轨。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2017-02-07
    • 2020-08-30
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    相关资源
    最近更新 更多