搜索1GB CSV文件

时间:2011-11-10 09:42:26

标签: c# .net performance file csv

我有一个CSV文件。每一行都由相同的格式组成,例如/

I,h,q,q,3,A,5,Q,3,[,5,Q,8,c,3,N,3,E,4,F,4,g,4,I,V,9000,0000001-100,G9999999990001800000000000001,G9999999990000001100PDNELKKMMCNELRQNWJ010, , , , , , ,D,Z,

我有Dictionary<string, List<char>>

通过打开文件,读取每一行,从行中获取元素并将其添加到字典来填充它,然后关闭文件。

字典在程序的其他地方使用,它接受输入数据到程序中,然后在字典中找到键,并使用24个元素与输入数据进行比较。

StreamReader s = File.OpenText(file);
 string lineData = null;
 while ((lineData = s.ReadLine()) != null)
 {
   var elements = lineData.Split(',');
   //Do stuff with elements
   var compareElements = elements.Take(24).Select(x => x[0]);
   FileData.Add(elements[27], new List<char>(compareElements));

  }
  s.Close();

我刚刚被告知CSV文件现在为800mb,其中有大约800万条记录。我刚刚尝试在我的双核Win 32位笔记本电脑上加载4GB RAM进行调试,并抛出一个OutOfMemoryException

我现在认为不将文件加载到内存中是最好的选择,但需要找到一种快速搜索文件的方法,以查看输入数据是否具有等于element[27]的匹配项,然后采取该CSV中的前24个元素,并将其与输入数据进行比较。

a)即使我坚持使用这种方法并且使用16GB内存并且Windows 64bit会使字典中的许多项目都可以吗?

b)如果您不认为使用字典是一个好计划,您能否提供一些快速搜索CSV文件的代码/链接

更新:虽然我已经接受了答案,但我只是想知道人们对使用FileStream进行查找然后提取数据的想法。

6 个答案:

答案 0 :(得分:4)

如果您打算搜索这么多记录,我建议将文件批量插入到DBMS之类的DBMS中,并为您的标准字段提供适当的索引,然后使用SQL查询检查是否存在记录。

答案 1 :(得分:0)

我们在导入包含需要聚合的数据的大型csv文件时遇到了类似的问题。最后,我们对SQL Server表进行了批量插入,并使用SQL来执行聚合。最后它很快(端到端几分钟)。

答案 2 :(得分:0)

您可以使用多种选项,但是,我同意将此数据加载到内存中并不是最佳选择。

a)您可以将数据加载到关系数据库中,尽管这对于此类数据可能过度。

b)您可以使用像RavenDB这样的NoSQL解决方案。我认为这对你来说可能是一个不错的选择。

c)您可以使用更有效的物理存储选项,例如Lucene

d)您可以使用更有效的内存/缓存选项,例如Redis

答案 3 :(得分:0)

解决方案可以将文件分解为一些较小的文件,并在每个文件中进行并行搜索 搜索顺序将小于或等于n(读取整个文件)

答案 4 :(得分:0)

由于你的程序的其余部分使用StringDictionary条目,你仍然理想地需要将结果存储在内存中 - 你真的不想要查询DB 1000次。 (这可能取决于您的程序是否存在于数据库服务器上)!

我会查看StringDictionary对你的结构的内存使用情况,看看你的理论最大值是多少,看看你是否可以在功能要求的警告中介绍它。否则,寻找更有效的存储方式 - 例如,将结果流式传输到XML文件比访问数据库更快。

答案 5 :(得分:0)

  • 忘记MS访问权限。真。
  • 尝试sqlite,这对于几百万行来说已经足够了
  • 如果您无法索引数据,则不要使用数据库,使用egrep等外部实用程序和相应的正则表达式来搜索特定字段。它会快得多。