【问题标题】:How to deal with very large databases如何处理非常大的数据库
【发布时间】:2013-02-22 00:11:34
【问题描述】:

我有一个DataTable,其中可以放置数十万条记录。这是一个巨大的内存开销,所以我添加了一个功能,用户只能在我的应用程序中可视化前 200 条记录,并且可以将其余结果导出到 CSV 文件。

但是,为了导出到 CSV 文件,我使用的方法是将DataTable 的内容转换为 CSV 文件。由于我可以在 DataTable 中有超过 100K 的记录,我认为将所有记录放入 DataTable 并映射到 CSV 文件会占用太多内存。会推荐什么方法?这是我的 CSV 映射代码:

StringBuilder builder = new StringBuilder();

            IEnumerable<string> columnNames = dtResults.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
            builder.AppendLine(string.Join(",", columnNames));

            foreach (DataRow row in dtResults.Rows)
            {
                IEnumerable<string> fields = row.ItemArray.Select(field => DisplayCommas(field.ToString()));
                builder.AppendLine(string.Join(",", fields));
            }

            File.WriteAllText(filename, builder.ToString());

【问题讨论】:

  • 数十万条记录是“中等”;不是“非常大”。当你开始意识到你需要做一些事情,比如“在服务器上排序和分页”,而不是把所有的东西都提取到DataTable 中时,就差不多到了这一点。您在这里使用的数据库是什么?您在这里使用“数据库”和“CSV”作为同义词吗?
  • @MarcGravell - 用户可以将我的应用程序应用于他们选择的任何数据库,因此理论上它可以与可用的最大数据库一样大(尽管这些情况很少)。用户可以使用我的应用程序来查询他们的数据库,并将他们的查询结果作为从 DataTable 生成的 DataGrid 查看。但是,我想将 DataTable 的内容导出到 CSV 文件,但是我担心可能存在 DataTable 会消耗太多内存的情况
  • 确实;因此,DataTable 在小型应用程序之外很少使用...
  • 如果您对数据库执行 IDataReader 以进行输出怎么办?不应产生巨大的内存开销。
  • 我想提出一个重要的事实,即您在控件中显示这个理论上很大的结果集。如果您想允许这种类型的 ui 访问,您将需要使用记录虚拟化和流式传输结果到网格。如果您认为构建 CSV 字符串会消耗大量内存,请等到您看到渲染从相同数据填充的网格控件的消耗。

标签: c# .net wpf database performance


【解决方案1】:

正如其他人所建议的那样,鉴于您的要求,应避免在此处使用重量级 DataTable。因此,使用其提供者的数据读取器从源中流式传输数据将为您提供最佳性能,同时保持纤薄的内存配置文件。

我进行了一些快速搜索,但找不到任何吹捧使用 DataReader 即插即用的简单 csv 库实现(有很多,远非详尽的搜索)。然而,使用 CSV 库(我之前成功使用过 FileHelpers 和 kbcsv)来处理文件写入、从查询中加载数据读取器、在开始循环之前告诉 csv 写入器列名然后只需让作者处理将结果流式传输到磁盘即可。

在此期间您可能会增加一些内存,因为文件写入流可能会有一个不错的缓冲区,但与以数据表为中心的方法相比,它会方式减少内存消耗。以这种方式使用具有大型结果集的数据读取器,我真正看到的唯一缺点是长时间运行的查询可能会从 ADO.NET 数据提供程序中消耗,但这完全是提供程序特定的(但一个常见问题)走这条路后,您可以查看数据库方面是否存在问题。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    我会去老学校并使用 sqlcmd。比如:

    sqlcmd -q "select field1,field2,field3 from mytable" -oc:\output.csv -h-1 -s","
    

    http://msdn.microsoft.com/en-us/library/ms162773.aspx

    【讨论】:

    • 这可以在 C# 中使用吗?此外,我还想将结果导出到 XML 和 Excel - 是否可以修改此解决方案以支持这些格式,还是仅支持 CSV?
    • 您忽略了上面提到的 XML 或 Excel。对于 XML,我会使用 SELECT FOR XML 子句 (msdn.microsoft.com/en-us/library/ms178107.aspx)。 Excel可以打开.csv文件
    【解决方案3】:

    放弃 DataTable 并使用 DataReader。依次读取您需要的记录并随时构建 CSV 文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-03
      • 1970-01-01
      • 1970-01-01
      • 2013-05-30
      相关资源
      最近更新 更多