最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#在MySQL大量數(shù)據(jù)下的高效讀取、寫入詳解

 更新時(shí)間:2016年11月28日 09:47:52   投稿:daisy  
最近由于工作的原因,經(jīng)常需要對(duì)海量數(shù)據(jù)進(jìn)行處理,做的數(shù)據(jù)爬蟲相關(guān),動(dòng)輒千萬(wàn)級(jí)別的數(shù)據(jù),單表幾十個(gè)G 都是都是家常便飯。 那么主要的開發(fā)語(yǔ)言是C#,數(shù)據(jù)庫(kù)使用的是MySQL。下面通過(guò)這篇文章我們來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。

前言

C#操作MySQL大量數(shù)據(jù)最常見的操作便是 select 讀取數(shù)據(jù),然后在C#中對(duì)數(shù)據(jù)進(jìn)行處理, 完畢后再插入數(shù)據(jù)庫(kù)中。  簡(jiǎn)而言之就 select -> process -> insert 三個(gè)步驟。 對(duì)于數(shù)據(jù)量小的情況下(百萬(wàn)級(jí)別 or 幾百兆)可能

最多1個(gè)小時(shí)就處理完了。但是對(duì)于千萬(wàn)級(jí)數(shù)據(jù)可能幾天,甚至更多。 那么問(wèn)題來(lái)了,如何優(yōu)化??

第一步 解決讀取的問(wèn)題

跟數(shù)據(jù)庫(kù)打交道的方式有很多,我來(lái)列舉下吧:

1. 【重武器-坦克大炮】使用重型ORM框架,比如 EF,NHibernat 這樣的框架。

2. 【輕武器-AK47】 使用 Dapper,PetaPoco 之類,單cs文件。靈活高效,使用簡(jiǎn)單。居家越貨必備(我更喜歡PetaPoco :))

3. 【冷兵器?匕首?】使用原生的Connection、Command。 然后寫原生的SQL語(yǔ)句。。

分析:

【重武器】在我們這里肯定直接被PASS, 他們應(yīng)該被用在大型項(xiàng)目中。

【輕武器】 Dapper,PetaPoco 看過(guò)源碼你會(huì)發(fā)現(xiàn)用到了反射,雖然使用 IL和緩存技術(shù) ,但是還是會(huì)影響讀取效率,PASS

好吧那就只有使用匕首, 原生SQL 走起, 利用 DataReader 進(jìn)行高效讀取,并且使用 索引 取數(shù)據(jù)(更快),而不是列名。

大概的代碼如下:

using (var conn = new MySqlConnection("Connection String..."))
{
 conn.Open();
 //此處設(shè)置讀取的超時(shí),不然在海量數(shù)據(jù)時(shí)很容易超時(shí)
 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`";
 //設(shè)置命令的執(zhí)行超時(shí)
 rcmd.CommandTimeout = 99999999;
 var myData = rcmd.ExecuteReader();

 while (myData.Read())
 {
  var f1= myData.GetInt32(0);
  var f2= myData.GetString(1);
  //這里做數(shù)據(jù)處理....
 }
}

哈哈,怎么樣,代碼非常原始,還是使用索引來(lái)取數(shù)據(jù),很容易出錯(cuò)。  當(dāng)然一切為了性能咱都忍了

第二步 數(shù)據(jù)處理

其實(shí)這一步,根據(jù)你的業(yè)務(wù)需要,代碼肯定不一, 不過(guò)無(wú)非是一些 字符串處理 , 類型轉(zhuǎn)換 的操作,這時(shí)候就是考驗(yàn)?zāi)愕腃#基礎(chǔ)功底的時(shí)候了。 以及如何高效編寫正則表達(dá)式。。。

具體代碼也沒法寫啊 ,先看完 CLR via C# 在來(lái)跟我討論吧 ,O(∩_∩)O哈哈哈~ 跳過(guò)。。。。

第三部 數(shù)據(jù)插入

如何批量插入才最高效呢?  有同學(xué)會(huì)說(shuō), 使用 事務(wù) 啊,BeginTransaction, 然后EndTransaction。 恩,這個(gè)的確可以提高插入效率。 但是還有更加高效的方法,那就是合并insert語(yǔ)句。

那么怎么合并呢?

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

就是把values后面的全部用逗號(hào),鏈接起來(lái),然后一次性執(zhí)行 。

當(dāng)然不能一次性提交個(gè)100MB的SQL執(zhí)行,MySQL服務(wù)器對(duì)每次執(zhí)行命令的長(zhǎng)度是有限制的。 通過(guò) MySQL服務(wù)器端的 max_allowed_packet   屬性可以查看, 默認(rèn)是 1MB

咱們來(lái)看看偽代碼吧

 //使用StringBuilder高效拼接字符串
 var sqlBuilder = new StringBuilder();
 //添加insert 語(yǔ)句的頭
 string sqlHeader = "insert into table1 (`f1`,`f2`) values";
 sqlBuilder.Append(sqlHeader);
 using (var conn = new MySqlConnection("Connection String..."))
 {
  conn.Open();
  //此處設(shè)置讀取的超時(shí),不然在海量數(shù)據(jù)時(shí)很容易超時(shí)
  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`";
  //設(shè)置命令的執(zhí)行超時(shí)
  rcmd.CommandTimeout = 99999999;
  var myData = rcmd.ExecuteReader();
  while (myData.Read())
  {
   var f1 = myData.GetInt32(0);
   var f2 = myData.GetString(1);
   //這里做數(shù)據(jù)處理....
   sqlBuilder.AppendFormat("({0},'{1}'),", f1,AddSlash(f2));
   if (sqlBuilder.Length >= 1024 * 1024 * 1024)//當(dāng)然這里的1MB length的字符串并不等于 1MB的Packet。。。我知道:)
   {
    insertCmd.Execute(sqlBuilder.Remove(sqlBuilder.Length-1,1).ToString())//移除逗號(hào),然后執(zhí)行
    sqlBuilder.Clear();//清空
    sqlBuilder.Append(sqlHeader);//在加上insert 頭
   }
  }
}

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

總結(jié)

總結(jié)下來(lái),無(wú)非2個(gè)關(guān)鍵技術(shù)點(diǎn), DataReader、SQL合并, 都是一些老的技術(shù)啦。其實(shí),上面的代碼只能稱得上高效, 但是, 卻非常的不優(yōu)雅。以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家能有所幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • C#中HttpWebRequest、WebClient、HttpClient的使用詳解

    C#中HttpWebRequest、WebClient、HttpClient的使用詳解

    這篇文章主要介紹了C#中HttpWebRequest、WebClient、HttpClient的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • C#傳值方式實(shí)現(xiàn)不同程序窗體間通信實(shí)例

    C#傳值方式實(shí)現(xiàn)不同程序窗體間通信實(shí)例

    Form2構(gòu)造函數(shù)中接收一個(gè)string類型參數(shù),即Form1中選中行的文本,將Form2的TextBox控件的Text設(shè)置為該string,即完成了Form1向Form2的傳值
    2013-12-12
  • C#中泛型容器Stack<T>的用法并實(shí)現(xiàn)”撤銷/重做”功能

    C#中泛型容器Stack<T>的用法并實(shí)現(xiàn)”撤銷/重做”功能

    這篇文章介紹了C#中泛型容器Stack<T>的用法并實(shí)現(xiàn)”撤銷/重做”功能,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • c#固定長(zhǎng)度的隨機(jī)字符串例子

    c#固定長(zhǎng)度的隨機(jī)字符串例子

    c#固定長(zhǎng)度的隨機(jī)字符串例子,需要的朋友可以參考一下
    2013-04-04
  • C# 解壓gizp文件(.tgz)的實(shí)例

    C# 解壓gizp文件(.tgz)的實(shí)例

    下面小編就為大家分享一篇C# 解壓gizp文件(.tgz)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • C#中使用HttpDownLoadHelper下載文件實(shí)例

    C#中使用HttpDownLoadHelper下載文件實(shí)例

    這篇文章主要介紹了C#中使用HttpDownLoadHelper下載文件的方法,并實(shí)例講述了在webfrom中與在mvc中的實(shí)現(xiàn)方法,需要的朋友可以參考下
    2014-10-10
  • C#中FTP常用操作的示例代碼

    C#中FTP常用操作的示例代碼

    這篇文章主要為大家詳細(xì)介紹了C#中FTP常用操作的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04
  • 輕松學(xué)習(xí)C#的基礎(chǔ)入門

    輕松學(xué)習(xí)C#的基礎(chǔ)入門

    輕松學(xué)習(xí)C#的基礎(chǔ)入門,了解C#最基本的知識(shí)點(diǎn),C#是一種簡(jiǎn)潔的,類型安全的一種完全面向?qū)ο蟮拈_發(fā)語(yǔ)言,是Microsoft專門基于.NET Framework平臺(tái)開發(fā)的而量身定做的高級(jí)程序設(shè)計(jì)語(yǔ)言,需要的朋友可以參考下
    2015-11-11
  • C#開源的AOP框架--KingAOP基礎(chǔ)

    C#開源的AOP框架--KingAOP基礎(chǔ)

    這篇文章主要介紹了一款C#開源的AOP框架--KingAOP框架的基礎(chǔ)知識(shí),對(duì)于想學(xué)習(xí)AOP的小伙伴來(lái)說(shuō),非常不錯(cuò),希望大家能夠喜歡。
    2015-12-12
  • Untiy Shader實(shí)現(xiàn)紋理貼圖滾動(dòng)

    Untiy Shader實(shí)現(xiàn)紋理貼圖滾動(dòng)

    這篇文章主要為大家詳細(xì)介紹了Untiy Shader實(shí)現(xiàn)紋理貼圖滾動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-03-03

最新評(píng)論

海城市| 北碚区| 沙河市| 丰都县| 冕宁县| 桦甸市| 婺源县| 龙陵县| 油尖旺区| 隆安县| 桃江县| 绍兴县| 堆龙德庆县| 南城县| 旬邑县| 深水埗区| 保定市| 伊金霍洛旗| 雷波县| 阳东县| 二连浩特市| 内丘县| 攀枝花市| 双牌县| 晋宁县| 桂平市| 肃北| 区。| 玉龙| 田阳县| 德惠市| 普宁市| 建瓯市| 杂多县| 宜昌市| 公主岭市| 宣武区| 望江县| 石阡县| 布尔津县| 十堰市|