2011-10-07 99 views
4

這是我的問題..導出大量的數據

我們有2種類型的報告在我們的網站,數據顯示在網格和數據即時下載爲報告。

這些報告可能包含幾年的數據(超過一百萬行),我們一直允許客戶根據日期範圍下載數據,但我們已經開始限制他們查看數據的時間以防止出現性能問題在我們的網站。然而,即使在一個小的日期範圍內,數據仍然變得非常大,現在它們正在擴展,並且如果它們下載太多,我們的內存會超過幾個演出並耗盡內存。

問題我有,我寧願不限制他們的數據,所以我想找出一個好的解決方案,讓他們下載儘可能多的,他們想要的。

我可以通過僅返回每頁數據來限制他們看到的內容,因此沒有性能問題,但下載始終是問題。

我已經看過異步,但沒有成功地得到它的工作,因爲它在加載數據時激發內存。

想法?思考?建議?

代碼示例:

 

// 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(); 

當我與我的數據..這是大約80萬行,我的記憶尖峯運行此,我得到一個內存不足的錯誤,並且使事情變得更糟..它總是豬在RenderControl直到它完成

+0

獲得更多的信息,爲什麼不乾脆扔在硬件的問題,並添加一些新的內存條?這些日子他們很便宜。 – ashes999

+1

這不是一個選項,不能因爲內存問題而增加ram,特別是因爲報告通常會高達4GB – jaekie

回答

2

我假設數據來自後端數據庫。如果是這樣,您不應讓用戶等待此操作完成。這是一個糟糕的UI設計,尤其是當內存可以達到4GB時。

我同意其他建議,您應該考慮改進代碼和設計,以減少佔用空間。但無論如何,你應該擁有像這樣的預定工作架構。

您讓用戶在搜索/文件上點擊下載,並將其添加到數據庫表中的隊列中。有一個db/.net進程來處理這些作業,並在服務器上以正確的格式生成一個文件。如果數據相同,並且使用適當的命名約定,則可以跨許多用戶重用該文件。然後,用戶應該能夠進入下載隊列頁面並查看他已安排的所有下載內容。一旦完成,他將能夠下載該文件。

如果你有一個要求不會讓你這樣做,請發表評論解釋它。

+0

這是我在腦海中想到的一個想法,但仍試圖找出如何獲得數據,因爲它試圖獲取數據,所以我不得不發送標準或用戶想要的,所以第三方工作可以拉動而不是網站 – jaekie

+1

這個網站是有區別的這樣做和另一臺服務器執行作業。網站將暫停或使其成爲非常痛苦的體驗。你可以做的是在db中實現一種類似於分頁的方式,並且只返回100k左右的數據塊,然後依次更新文件。 –

+0

這可能聽起來像是太多的工作,但一旦你一次採取一步,它會很簡單,你會在結束時感到自豪:) –

1

好了,我們開始吧:

  • DONT使用表
  • DONT使用DataSet

完成。

獲取數據讀取器,隨時寫入HTML - 您永遠不會將所有數據保存在內存中。你的方法永遠不會擴展。

+0

只需添加到這一點,使用表格意味着你必須加載所有數據存儲到內存中,然後在渲染期間將所有數據複製到輸出中,所以現在您在內存中有2個副本。即使使用數據讀取器也會有助於減少加載到內存中的數據量。 –

+2

再加上你不會緩存輸出 - 你可以把它輸出。在msot情況下,數據表是不好的,因爲這會使得數據的渲染變得非常糟糕。 – TomTom

0

你可以重寫存儲過程分頁並循環訪問數據集嗎?然後重寫輸出部分以流式傳輸文件,而不是一次輸出全部文件(目前的方法基本上只是寫出HTML表格)。

分頁數據將保持下載過程從內存中存儲所有的數據

0

解決了!

同樣的問題是當我在Excel中導出大量數據時遇到的問題。

解決方案:您可以使用打開XMl DLL來解決您的問題。 使用這個DLL你可以在Excel中導出大量的數據,並且內存消耗也會更少。

你可以從這裏 https://msdn.microsoft.com/en-us/library/office/hh180830(v=office.14).aspx

+0

這是Open XML上的另一個堆棧溢出解決方案http://stackoverflow.com/questions/11370672/export-a-large-data-query-60k-rows-to-excel/42304339#42304339 – Greg