自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

詳解C#中利用ODP實(shí)現(xiàn)瞬間導(dǎo)入百萬級(jí)數(shù)據(jù)

開發(fā) 后端
在這里我們將看到的是C#中利用ODP實(shí)現(xiàn)在Oracle數(shù)據(jù)庫中瞬間導(dǎo)入百萬級(jí)數(shù)據(jù),這對(duì)快速批量導(dǎo)入的實(shí)現(xiàn)有重要意義。

 .NET程序中可以通過ODP調(diào)用特性,對(duì)Oracle數(shù)據(jù)庫進(jìn)行操作,今天來講一下數(shù)據(jù)批量插入的功能,所用技術(shù)不高不深,相信很多朋友都接觸過,小弟班門弄斧了,呵呵。這篇文章是上篇文章的續(xù)集,因?yàn)樯弦淮卧囼?yàn)的征集結(jié)果沒有突破4秒的方法,所以這次繼續(xù)挑戰(zhàn)與挖掘新方法,雖然是Oracle,但仍具有一定收藏意義。

上一次文章中提及的試驗(yàn):

極限挑戰(zhàn)—C#100萬條數(shù)據(jù)導(dǎo)入SQL SERVER數(shù)據(jù)庫僅用4秒 (附源碼)

http://www.cnblogs.com/isline/archive/2010/03/18/1688783.html

這個(gè)試驗(yàn)是針對(duì)SQL SERVER數(shù)據(jù)庫的,宿主環(huán)境也是.NET,有興趣的朋友可以將這兩個(gè)試驗(yàn)對(duì)比一下,為日后工作批量導(dǎo)數(shù)提供支持。

另外,一些朋友對(duì)上次試驗(yàn)環(huán)境有些異議,認(rèn)為應(yīng)該對(duì)數(shù)據(jù)庫和服務(wù)器做優(yōu)化或設(shè)置,以體現(xiàn)試驗(yàn)最終的時(shí)間結(jié)果。這個(gè)固然會(huì)影響試驗(yàn)的時(shí)間結(jié)果,但考慮到在試驗(yàn)環(huán)境中,對(duì)數(shù)據(jù)庫優(yōu)化的標(biāo)準(zhǔn)與優(yōu)化程度不便統(tǒng)一與定量,試驗(yàn)結(jié)果也不易說明其影響源,所以這次試驗(yàn)依然以標(biāo)準(zhǔn)數(shù)據(jù)庫建庫后的配置為主,試驗(yàn)所在服務(wù)器硬件環(huán)境與上次試驗(yàn)保持一致。實(shí)驗(yàn)?zāi)康脑谟谕诰?、?duì)比宿主程序中的數(shù)據(jù)批量操作方法。

有新方法提升性能時(shí)間指標(biāo)的朋友,歡迎互相切磋,互相提高,嘴上功夫就免了。。。

好了正文開始。

普通肉墊式

什么叫批量插入呢,就是一次性插入一批數(shù)據(jù),我們可以把這批數(shù)據(jù)理解為一個(gè)大的數(shù)組,而這些全部只通過一個(gè)SQL來實(shí)現(xiàn),而在傳統(tǒng)方式下,需要調(diào)用很多次的SQL才可以完成,這就是著名的“數(shù)組綁定”的功能。我們先來看一下傳統(tǒng)方式下,插入多行記錄的操作方式:

  1. //設(shè)置一個(gè)數(shù)據(jù)庫的連接串,   
  2. string connectStr = "User Id=scott;Password=tiger;Data Source=";   
  3. OracleConnection conn = new OracleConnection(connectStr);  
  4.  OracleCommand command = new OracleCommand(); 
  5. command.Connection = conn; conn.Open();   
  6. Stopwatch sw = new Stopwatch();   
  7. sw.Start(); //通過循環(huán)寫入大量的數(shù)據(jù),這種方法顯然是肉墊   
  8. for (int i = 0; i < recc; i++)   
  9. {   
  10. string sql = "insert into dept values(" + i.ToString() 
  11. "," + i.ToString() + "," + i.ToString() + ")";  
  12. command.CommandText = sql;   
  13. command.ExecuteNonQuery();   
  14. }  
  15.  sw.Stop();  
  16. System.Diagnostics.Debug.WriteLine("普通插入:" + recc.ToString()
  17.  + "所占時(shí)間:" + sw.ElapsedMilliseconds.ToString());   

我們先準(zhǔn)備好程序,但是先不做時(shí)間的測(cè)定,因?yàn)樵诤竺嫖覀儠?huì)用多次循環(huán)的方式來計(jì)算所占用的時(shí)間。

使用ODP特性

看上面的程序,大家都很熟悉,因?yàn)樗鼪]有用到任何ODP的特性,而緊接著我們就要來介紹一個(gè)神奇的程序了,我們看一下代碼,為了更直觀,我把所有的注釋及說明直接寫在代碼里:

  1. //設(shè)置一個(gè)數(shù)據(jù)庫的連接串   
  2. string connectStr = "User Id=scott;Password=tiger;Data Source=";   
  3. OracleConnection conn = new OracleConnection(connectStr);   
  4. OracleCommand command = new OracleCommand();   
  5. command.Connection = conn; //到此為止,還都是我們熟悉的代碼,下面就要開始嘍   
  6. //這個(gè)參數(shù)需要指定每次批插入的記錄數(shù)   
  7. command.ArrayBindCount = recc;   
  8. //在這個(gè)命令行中,用到了參數(shù),參數(shù)我們很熟悉,但是這個(gè)參數(shù)在傳值的時(shí)候   
  9. //用到的是數(shù)組,而不是單個(gè)的值,這就是它獨(dú)特的地方   
  10. command.CommandText = "insert into dept values(:deptno, :deptname, :loc)";   
  11. conn.Open();   
  12. //下面定義幾個(gè)數(shù)組,分別表示三個(gè)字段,數(shù)組的長(zhǎng)度由參數(shù)直接給出   
  13. int[] deptNo = new int[recc];   
  14. string[] dname = new string[recc];   
  15. string[] loc = new string[recc];   
  16. // 為了傳遞參數(shù),不可避免的要使用參數(shù),下面會(huì)連續(xù)定義三個(gè)   
  17. // 從名稱可以直接看出每個(gè)參數(shù)的含義,不在每個(gè)解釋了   
  18. OracleParameter deptNoParam = new OracleParameter("deptno",   
  19. OracleDbType.Int32);   
  20. deptNoParam.Direction = ParameterDirection.Input;   
  21. deptNoParam.Value = deptNo; command.Parameters.Add(deptNoParam);   
  22. OracleParameter deptNameParam = new OracleParameter("deptname",   
  23. OracleDbType.Varchar2);  
  24. deptNameParam.Direction = ParameterDirection.Input;   
  25. deptNameParam.Value = dname;   
  26. command.Parameters.Add(deptNameParam);  
  27.  OracleParameter deptLocParam = new OracleParameter("loc", OracleDbType.Varchar2); 
  28. deptLocParam.Direction = ParameterDirection.Input;  
  29.  deptLocParam.Value = loc;   
  30. command.Parameters.Add(deptLocParam);   
  31. Stopwatch sw = new Stopwatch();   
  32. sw.Start();   
  33. //在下面的循環(huán)中,先把數(shù)組定義好,而不是像上面那樣直接生成SQL   
  34. for (int i = 0; i < recc; i++)  
  35. {   
  36. deptNo[i] = i;   
  37. dname[i] = i.ToString();   
  38. loc[i] = i.ToString();   
  39. }   
  40. //這個(gè)調(diào)用將把參數(shù)數(shù)組傳進(jìn)SQL,同時(shí)寫入數(shù)據(jù)庫   
  41. command.ExecuteNonQuery(); 
  42. sw.Stop(); 
  43. System.Diagnostics.Debug.WriteLine("批量插入:" + recc.ToString()   
  44. "所占時(shí)間:" +sw.ElapsedMilliseconds.ToString());  

以上代碼略顯冗長(zhǎng),但是加上注釋后基本也就表達(dá)清楚了。

好了,到目前為止,兩種方式的插入操作程序已經(jīng)完成,就剩下對(duì)比了。我在主函數(shù)處寫了一個(gè)小函數(shù),循環(huán)多次對(duì)兩個(gè)方法進(jìn)行調(diào)用,并且同時(shí)記錄下時(shí)間,對(duì)比函數(shù)如下:

  1. for (int i = 1; i <= 50; i++)  
  2.  {   
  3. Truncate();   
  4. OrdinaryInsert(i * 1000); Truncate();   
  5. BatchInsert(i * 1000);  
  6.  }  

當(dāng)數(shù)據(jù)量達(dá)到100萬級(jí)別時(shí),所用時(shí)間依然令人滿意,最快一次達(dá)到890毫秒,一般為1秒左右。

經(jīng)過試驗(yàn),得出一組數(shù)據(jù),可以看出兩種方式在效率方面驚人的差距(占用時(shí)間的單位為毫秒),部分?jǐn)?shù)據(jù)如下:
 

記錄數(shù)

標(biāo)準(zhǔn)

批處理

1000

1545

29

2000

3514

20

3000

3749

113

4000

5737

40

5000

6820

52

6000

9469

72

7000

10226

69

8000

15280

123

9000

11475

83

10000

14536

121

11000

15705

130

12000

16548

145

13000

18765

125

14000

20393

116

15000

22181

159

 
因?yàn)槠?,不再粘貼全部的數(shù)據(jù),但是我們可以看一下由此數(shù)據(jù)生成的散點(diǎn)圖:

clip_image002

其中有些數(shù)據(jù)有些跳躍,可能和數(shù)據(jù)庫本身有關(guān)系,但是大部分?jǐn)?shù)據(jù)已經(jīng)能說明問題了??戳诉@些數(shù)據(jù)后,是不是有些心動(dòng)了?

源程序放了一段時(shí)間直接拷貝貼過來了,可能需要調(diào)試一下才能跑通,不過不是本質(zhì)性問題,對(duì)了如果要測(cè)試別忘記安裝Oracle訪問組件。

原文標(biāo)題:極限挑戰(zhàn)—C#+ODP 100萬條數(shù)據(jù)導(dǎo)入Oracle數(shù)據(jù)庫僅用不到1秒

鏈接:http://www.cnblogs.com/isline/archive/2010/08/31/1813722.html

【編輯推薦】

  1. C#模式窗體中的按鈕操作
  2. C#模式窗體操作詳解
  3. C#窗體繼承原理以及實(shí)現(xiàn)淺析
  4. C#窗體關(guān)閉事件的重載實(shí)現(xiàn)淺析
  5. C#窗體位置與大小設(shè)置詳解

責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2011-07-12 14:08:48

OracleODAC

2010-03-22 09:59:46

SQL Server

2024-04-09 13:20:00

Excel數(shù)據(jù)庫數(shù)據(jù)

2024-08-05 09:51:00

2009-08-25 18:04:30

C#實(shí)現(xiàn)Singlet

2009-09-09 18:50:23

C# 加密RSA

2009-08-31 16:23:13

C#接口

2009-01-19 10:26:02

C#Namespace.NET

2009-08-28 15:32:39

C#利用WMI獲取數(shù)據(jù)

2009-09-09 18:57:26

C# 加密TripleDES

2009-08-25 17:43:17

C#串口監(jiān)聽

2009-08-25 10:44:50

C#實(shí)現(xiàn)多語言

2009-08-21 10:13:02

C#異步初步

2009-08-26 09:22:44

C#實(shí)現(xiàn)打印功能

2009-08-26 11:07:36

C#打印窗體

2009-08-26 11:32:37

C#打印文檔

2009-08-26 12:59:08

C#打印設(shè)置

2025-02-06 08:06:05

2009-08-19 16:50:32

Visual C#C#語言特性

2011-04-20 14:28:38

SQL優(yōu)化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)