国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數據庫技術|

服務器之家 - 數據庫 - Mysql - C#如何在海量數據下的高效讀取寫入MySQL

C#如何在海量數據下的高效讀取寫入MySQL

2020-07-05 16:45花生!~~ Mysql

這篇文章主要介紹了C#如何在海量數據下的高效讀取寫入MySQL的相關資料,需要的朋友可以參考下

前提

由于工作的原因,經常需要對海量數據進行處理,做的數據爬蟲相關,動輒千萬級別的數據,單表幾十個G都是都是家常便飯。  主要開發語言是C#,數據庫使用的是MySQL

最常見的操作便是 select 讀取數據,然后在C#中對數據進行處理, 完畢后再插入數據庫中。  簡而言之就 select -> process -> insert三個步驟。 對于數據量小的情況下(百萬級別 or 幾百兆)可能最多1個小時就處理完了。但是對于千萬級數據可能幾天,甚至更多。 那么問題來了,如何優化??

C#如何在海量數據下的高效讀取寫入MySQL

 (數據庫的一覽,有圖有真相)

第一步 解決讀取的問題

跟數據庫打交道的方式有很多,我來列舉下吧:

1. 【重武器-坦克大炮】使用重型ORM框架,比如EF,NHibernat 這樣的框架。
2. 【輕武器-AK47】 使用Dapper,PetaPoco之類,單cs文件。靈活高效,使用簡單。居家越貨必備(我更喜歡PetaPoco :))
3. 【冷兵器?匕首?】使用原生的Connection、Command。 然后寫原生的SQL語句。。

分析:

【重武器】在我們這里肯定直接被PASS, 他們應該被用在大型項目中。 

【輕武器】Dapper,PetaPoco 看過源碼你會發現用到了反射,雖然使用IL和緩存技術,但是還是會影響讀取效率,PASS
好吧那就只有使用匕首,原生SQL走起, 利用DataReader 進行高效讀取,并且使用索引取數據(更快),而不是列名。
大概的代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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哈哈哈~ 跳過。。。。

第三部 數據插入

如何批量插入才最高效呢?  有同學會說, 使用事務啊,BeginTransaction, 然后EndTransaction。 恩,這個的確可以提高插入效率。 但是還有更加高效的方法,那就是合并insert語句。

那么怎么合并呢?

?
1
insert into table (f1,f2) values(1,'sss'),values(2,'bbbb'),values(3,'cccc');

就是把values后面的全部用逗號,鏈接起來,然后一次性執行 。

當然不能一次性提交個100MB的SQL執行,MySQL服務器對每次執行命令的長度是有限制的。 通過 MySQL服務器端的max_allowed_packet  屬性可以查看, 默認是1MB

咱們來看看偽代碼吧

?
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
31
32
//使用StringBuilder高效拼接字符串
 var sqlBuilder = new StringBuilder();
 //添加insert 語句的頭
 string sqlHeader = 'insert into table1 (`f1`,`f2`) values';
 sqlBuilder.Append(sqlHeader);
 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);
     //這里做數據處理....
     sqlBuilder.AppendFormat('({0},'{1}'),', f1,AddSlash(f2));
     if (sqlBuilder.Length >= 1024 * 1024)//當然這里的1MB length的字符串并不等于 1MB的Packet。。。我知道:)
     {
       insertCmd.Execute(sqlBuilder.Remove(sqlBuilder.Length-1,1).ToString())//移除逗號,然后執行
       sqlBuilder.Clear();//清空
       sqlBuilder.Append(sqlHeader);//在加上insert 頭
     }
   }
}

好了,到這里 大概的優化后的高效查詢、插入就完成了。 

結語

總結下來,無非2個關鍵技術點,DataReader、SQL合并,都是一些老的技術啦。

其實,上面的代碼只能稱得上 高效 , 但是, 卻非常的不優雅。。。甚至難看。。。

那那么問題來了?  如何進行重構呢? 通過重構抽象出一個可用的類,而不必關心字符串拼接這些亂七八糟的東西,支持多線程合并寫入,最大限度提高寫入IO,  我們在下一篇文章中再來談談。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 久久精品欧美 | 成人av高清在线观看 | 国产 日韩 欧美 中文 在线播放 | 国产一区av在线 | 久久与欧美 | 国产精品免费精品自在线观看 | 亚洲国产精品一区二区三区 | 亚洲一区二区三区 | 欧美成人h版在线观看 | 亚洲精品一区二三区不卡 | 亚洲精品一区二区三区精华液 | 午夜视频导航 | 成人免费视频网 | 二区在线观看 | 日韩欧美一级电影 | 欧美一级二级视频 | 精品久久国产 | 亚洲精品乱码 | 老女肥熟av免费观看 | 日本精品在线 | 日韩av中文| 欧美在线观看免费观看视频 | 国产a自拍 | 午夜精品久久久久久 | 久久99精品久久久 | 2018啪一啪 | 91在线视频观看 | av网站免费看 | 成人网18免费网站 | zzz444成人天堂7777 | 国产精品久久久久久久久久久久 | 久久精品国产亚洲精品 | 午夜影视免费观看 | 黄色mm视频 | 国内自拍第一页 | 久久视频精品 | 亚洲精品综合中文字幕 | 亚洲精品久久久久久一区二区 | 精品一级| 一本久久a久久精品亚洲 | 福利在线播放 |