导出大量数据

Posted

技术标签:

【中文标题】导出大量数据【英文标题】:Exporting Large Amounts of Data 【发布时间】:2011-12-03 00:21:08 【问题描述】:

这是我的问题..

我们的网站中有两种类型的报告,以表格形式显示的数据和作为报告即时下载的数据。

这些报告可能包含几年的数据(1+ 百万行),我们一直允许客户下载某个日期范围内的数据,但我们已经开始限制他们查看数据的时间,以防止出现性能问题我们的网站。但是,即使在很小的日期范围内,数据仍然会变得相当大,因为它们正在扩展,如果它们下载太多,我们的内存会在几场演出中达到峰值并耗尽内存。

我的问题是,我宁愿不限制他们的数据,所以我试图找出一个好的解决方案,让他们想下载多少就下载多少。

我可以通过只返回每页数据来限制他们看到的内容,这样就不会出现性能问题,但下载始终是个问题。

我研究了异步,但未能成功地让它工作,因为它在我加载数据时会占用内存。

想法?想法?有什么建议吗?

代码示例:

// 获取数据 SqlConnection con = new SqlConnection(); SqlCommand cmd = 新的 SqlCommand(); SqlDataAdapter da; 数据集 ds = new DataSet(); con.ConnectionString = "我的连接字符串"; con.Open(); cmd.Connection = con; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = "MyStoredProc"; da = 新的 SqlDataAdapter(cmd); da.填充(ds); con.Close(); StringWriter sw = new StringWriter(); htmlTextWriter htw = new HtmlTextWriter(sw); 数据网格 dg = 新数据网格(); dg.DataSource = ds.Tables[0]; dg.DataBind(); dg.RenderControl(htw); Response.ClearContent(); Response.ContentType = "应用程序/vnd.ms-excel"; Response.AddHeader("Content-Disposition", "attachment;filename=Report.xls"); Response.Write(sw.ToString()); 响应。结束();

当我使用大约 800k 行的数据运行此程序时,我的内存会出现峰值,并且出现内存不足错误,并使事情变得更糟。它总是在 RenderControl 上运行,直到完成

【问题讨论】:

为什么不把硬件放在问题上并添加更多的 RAM 棒呢?这些天它们很便宜。 这不是一个选项,不能因为内存问题而仅仅增加内存,特别是因为报告通常会飙升至 4GB 【参考方案1】:

我假设数据来自后端数据库。如果是这样,您不应该让用户等待此操作完成。这是一个糟糕的 UI 设计,尤其是当内存可以达到 4GB 时。

我同意其他建议,您应该考虑改进代码和设计,可能有助于减少占用空间。但无论如何,您应该为此制定计划的作业架构。

您让用户在搜索/文件上点击下载,并将其添加到数据库表中的队列中。有一个 db/.net 进程出现并处理这些作业,并在服务器上生成正确格式的文件。如果数据相同并且您使用正确的命名约定,则可以在多个用户之间重复使用该文件。然后,用户应该能够转到下载队列页面并查看他已安排的所有下载。完成后,他将能够下载文件。

如果你有一个不允许你这样做的要求,请发表评论解释它。

【讨论】:

这是我脑海中的一个想法,但仍在试图弄清楚如何获取数据,因为它试图获取数据,所以我不得不发送标准或用户想要的内容,以便第三方工作可以拉取而不是网站 执行此操作的网站与执行该作业的另一台服务器之间存在差异。网站要么超时,要么使其成为非常痛苦的体验。你可以做的是在数据库中实现类似分页,只带回 100k 左右的块并按顺序更新文件。 这听起来可能工作量太大,但是一旦你一步一步迈出,它就会变得简单,最后你会感到自豪:)【参考方案2】:

好的,我们开始:

不要使用表格 不要使用数据集

完成。

获取数据阅读器,随手编写 HTML - 您永远不会将所有数据保存在内存中。你的方法永远不会扩展。

【讨论】:

只是补充一点,使用表意味着您必须将所有数据加载到内存中,然后在渲染期间将所有数据复制到输出中,因此您现在有 2 个副本记忆。即使使用数据读取器也有助于减少加载到内存中的数据量。 另外,您不需要缓存输出 - 您可以将其输出。数据表在 msot 情况下很糟糕,但是对于呈现大量数据,这变得非常糟糕。【参考方案3】:

能否重写存储过程以进行分页和循环遍历数据集?然后重写输出部分以流式传输文件,而不是一次性输出所有文件(您当前的方法基本上只是写出一个 HTML 表格)。

分页数据将使下载过程不会将所有数据存储在内存中

【讨论】:

【参考方案4】:

解决了!!!

当我在 Excel 中导出大量数据时,我也遇到了同样的问题。

解决方案:您可以使用 open XMl dll 来解决您的问题。 使用这个dll,你可以在excel中导出大量数据,内存消耗也会更少。

您可以从这里获得更多信息 https://msdn.microsoft.com/en-us/library/office/hh180830(v=office.14).aspx

【讨论】:

这是另一个关于 Open XML 的堆栈溢出解决方案 ***.com/questions/11370672/…

以上是关于导出大量数据的主要内容,如果未能解决你的问题,请参考以下文章

php怎么导出大量数据的Excel

php怎么导出大量数据的Excel

php怎么导出大量数据的Excel

php怎么导出大量数据的Excel

实现大量数据,份sheet导出

导出大量数据