前提
由于工作的原因,經常需要對海量數據進行處理,做的數據爬蟲相關,動輒千萬級別的數據,單表幾十個G都是都是家常便飯。  主要開發語言是C#,數據庫使用的是MySQL。
最常見的操作便是 select 讀取數據,然后在C#中對數據進行處理, 完畢后再插入數據庫中。 簡而言之就 select -> process -> insert三個步驟。 對于數據量小的情況下(百萬級別 or 幾百兆)可能最多1個小時就處理完了。但是對于千萬級數據可能幾天,甚至更多。 那么問題來了,如何優化??

 (數據庫的一覽,有圖有真相)
第一步 解決讀取的問題
跟數據庫打交道的方式有很多,我來列舉下吧:
1. 【重武器-坦克大炮】使用重型ORM框架,比如EF,NHibernat 這樣的框架。 
2. 【輕武器-AK47】 使用Dapper,PetaPoco之類,單cs文件。靈活高效,使用簡單。居家越貨必備(我更喜歡PetaPoco :))
3. 【冷兵器?匕首?】使用原生的Connection、Command。 然后寫原生的SQL語句。。
分析:
【重武器】在我們這里肯定直接被PASS, 他們應該被用在大型項目中。  
【輕武器】Dapper,PetaPoco 看過源碼你會發現用到了反射,雖然使用IL和緩存技術,但是還是會影響讀取效率,PASS
好吧那就只有使用匕首,原生SQL走起, 利用DataReader 進行高效讀取,并且使用索引取數據(更快),而不是列名。
大概的代碼如下:
| using (var conn = new MySqlConnection('Connection String...')){ conn.Open(); //此處設置讀取的超時,不然在海量數據時很容易超時 var c = new MySqlCommand('set net_write_timeout=9999999; set net_read_timeout=9999999', conn); c.ExecuteNonQuery(); MySqlCommand rcmd = new MySqlCommand(); rcmd.Connection = conn; rcmd.CommandText = @'SELECT `f1`,`f2` FROM `table1`'; //設置命令的執行超時 rcmd.CommandTimeout = 99999999; var myData = rcmd.ExecuteReader(); while (myData.Read()) { var f1= myData.GetInt32(0); var f2= myData.GetString(1); //這里做數據處理.... }} | 
哈哈,怎么樣,代碼非常原始,還是使用索引來取數據,很容易出錯。  當然一切為了性能咱都忍了
第二步 數據處理
其實這一步,根據你的業務需要,代碼肯定不一, 不過無非是一些字符串處理,類型轉換的操作,這時候就是考驗你的C#基礎功底的時候了。 以及如何高效編寫正則表達式。。。
具體代碼也沒法寫啊 ,先看完CLR via C# 在來跟我討論吧 ,O(∩_∩)O哈哈哈~ 跳過。。。。
新聞熱點
疑難解答