大資料文字讀取並儲存到MSSQL的坑
阿新 • • 發佈:2019-02-04
在此次大資料整理過程中,有一個文字檔案,裡面儲存著上百萬條日誌記錄,現在需要將其根據格式讀取出來後傳入到SQL Server。
檔案大小:兩百多MB,行數:六百多萬行,格式:TXT
當然是從自己最能上手的地方出發:C#,剛好以前做了一個通用版查詢分析器,直接一個DragDrop搞起。
通過DbProviderFactory建立與SQLServer的聯絡,並且獲得目標table結構之後,將檔案拖入,DragDrop語句如下:
(部分黏貼到VS無法識別的程式碼是自己的查詢方法,請根據中文含義另寫)
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); DataTable dt; using (StreamReader sr = new StreamReader(files[0],Encoding.Default)) { dt = ((DataTable)dgv.DataSource).Clone();//複製表模 string line; while ((line = sr.ReadLine()) != null) { string[] s = line.ToString().Split('#'); dt.Rows.Add(s[0].Trim(), s[1].Trim(), s[2].Trim()); }
dt更新(dt);//更新到資料庫
}
本來小資料量的話,這樣做是沒事的,然而我看著VS2015中的診斷工具,記憶體瞬間漲到1G,並且不斷的GC,總覺得資料量這麼大應該是正常的,結果坑來了:
.Net 記憶體溢位(System.OutOfMemoryException)
這個錯誤讓我糾結,仔細在網上搜索程式碼也沒說出是哪裡出的問題,結果看到一篇文章說直接update到資料庫,就在懷疑資料讀取的本身應該沒什麼問題,有可能是datatable的問題,果然更新了語句,讓每10W條就update一次,並且重新複製模板再繼續,這次就正常了。string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); DataTable dt; using (StreamReader sr = new StreamReader(files[0],Encoding.Default)) { dt = ((DataTable)dgv.DataSource).Clone(); int count = 0; string line; while ((line = sr.ReadLine()) != null) { string[] s = line.ToString().Split('#'); dt.Rows.Add(s[0].Trim(), s[1].Trim(), s[2].Trim()); count++; if (count > 100000) { dt更新(dt); dt = ((DataTable)dgv.DataSource).Clone(); count = 0; } } }
當然這種寫法是簡單粗暴的短期方法,長期這樣做對伺服器還是挺折騰的,但不折騰怎麼對得起自己強悍的電腦呢~
最主要的是,在自己能夠處理的方法內,問題解決。