Exporting Large Amounts of Data
这是我的问题……
我们的站点中有两种类型的报告,网格中显示的数据和作为报告即时下载的数据。
这些报告可以包含几年的数据(超过一百万行),我们允许客户根据日期范围下载数据,但我们开始限制他们查看数据的时间,以防止我们网站出现性能问题。然而,即使是在一个小的日期范围内,数据仍然变得相当大,因为它们正在扩展,如果下载太多,我们的内存就会超过几格,耗尽内存。
我的问题是,我不想限制他们的数据,所以我正试图找到一个好的解决方案,允许他们下载他们想要的。
我可以通过每页返回数据来限制他们看到的内容,这样就不会出现性能问题,但是下载始终是问题所在。
我已经研究过Async,但还没有成功地让它工作,因为它在加载数据时会增加内存。
思想?思想?建议?
代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // Get Data SqlConnection con = new SqlConnection(); SqlCommand cmd = new SqlCommand(); SqlDataAdapter da; DataSet ds = new DataSet(); con.ConnectionString ="MyConnectionString"; con.Open(); cmd.Connection = con; cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText ="MyStoredProc"; da = new SqlDataAdapter(cmd); da.Fill(ds); con.Close(); StringWriter sw = new StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw); DataGrid dg = new DataGrid(); dg.DataSource = ds.Tables[0]; dg.DataBind(); dg.RenderControl(htw); Response.ClearContent(); Response.ContentType ="application/vnd.ms-excel"; Response.AddHeader("Content-Disposition","attachment;filename=Report.xls"); Response.Write(sw.ToString()); Response.End(); |
当我用我的数据运行这个……大约有800K行,内存峰值,我会出现内存不足错误,使情况更糟。它总是在rendercontrol上猛冲直到完成
我假设数据来自后端数据库。如果是这样,则不应该让用户等待此操作完成。这是一个糟糕的用户界面设计,尤其是当内存可以达到4GB时。
我同意其他建议,即您应该考虑改进代码和设计,以帮助减少占地面积。但是无论如何,您应该有类似于计划的作业架构这样的东西。
您可以让用户点击搜索/文件上的"下载",然后将其添加到数据库表中的队列中。有一个db/.net进程来处理这些作业,并在服务器上以正确的格式生成文件。如果数据相同,并且使用适当的命名约定,那么可以跨多个用户重用该文件。然后,用户应该能够访问下载队列页面,查看他已安排的所有下载。一旦完成,他将能够下载文件。
如果你有一个不允许你这样做的要求,请发表评论解释。
好,我们走吧:
- 不要用桌子
- 不要使用数据集
完成了。
找一个数据阅读器,一边写HTML——你永远不会把所有的数据都保存在内存中。你的方法永远不会扩大。
解决了的!!!!
我在Excel中导出大量数据时也遇到了同样的问题。
解决方案:您可以使用开放式XML DLL来解决您的问题。使用此DLL,您可以在Excel中导出大量数据,并且内存消耗也会减少。
您可以从这里获得更多信息https://msdn.microsoft.com/en-us/library/office/hh180830(v=office.14).aspx
是否可以重写要分页的存储过程并在数据集中循环?然后重写输出部分以流式传输文件,而不是一次性全部输出(您当前的方法基本上只是写出一个HTML表)。
对数据进行分页可以防止下载过程将所有数据存储在内存中。