1. 程式人生 > >大資料文字讀取並儲存到MSSQL的坑

大資料文字讀取並儲存到MSSQL的坑

在此次大資料整理過程中,有一個文字檔案,裡面儲存著上百萬條日誌記錄,現在需要將其根據格式讀取出來後傳入到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;
                    }
                }

            }
                        

當然這種寫法是簡單粗暴的短期方法,長期這樣做對伺服器還是挺折騰的,但不折騰怎麼對得起自己強悍的電腦呢~

最主要的是,在自己能夠處理的方法內,問題解決。