文章出處

這里采用.NET Framework 4.0以上版本中新出現的 ConcurrentQueue<T> 類

MSDN是這樣描述的:

ConcurrentQueue<T> 類是一個線程安全的先進先出 (FIFO) 集合。

ConcurrentQueue<T> 的所有公共且受保護的成員都是線程安全的,可從多個線程同時使用。

共采用兩個線程,一個讀一個寫。

ConcurrentQueue<T>的實現方法:

(FIFO) 集合:

ConcurrentQueue<DataTable> DataTableList = new ConcurrentQueue<DataTable>();

讀:

 1 private void MainThread()
 2 {
 3     if (DataTableList.Count < _pageCount)//小于隊列最大值后即可再次獲取一次
 4     {
 5         for (int index = 0; index < _pageCount; index++)
 6         {
 7             DataTable dt = null;
 8             try
 9             {
10                 int counts = index == 0 ? index : (index * PageSize - 1);
11                 dt = MySql.GetDataTable(counts, PageSize);
12                 DataTableList.Enqueue(dt);
13                 Console.WriteLine("Read {0}\t{1}/{2}", DateTime.Now.ToString("HH:mm:ss.fff"), index, counts);
14             }
15             catch (Exception)
16             { }
17             ThreadPool.QueueUserWorkItem(Thread1, dt);
18         }
19     }
20 }

寫:

 1 private void Thread1(object state)
 2 {
 3     var dt = (DataTable)state;
 4     MsSql.Insert(dt);
 5     Console.WriteLine("Write {0}", DateTime.Now.ToString("HH:mm:ss.fff"));
 6     OK_WORK_COUNT++;//已處理任務數+1
 7     //從任務隊列移除
 8     if (DataTableList.Count > 0)
 9     {
10         DataTableList.TryDequeue(out dt);
11     }
12 }

讀取MySQL數據庫的方法很簡單:

MySqlDataAdapter.Fill(DataTable dataTable)方法填充數據。

寫入MSSQL數據庫的方法也很簡單:

SqlBulkCopy.WriteToServer(DataTable dataTable)方法批量插入數據。

經過多次測試,程序上的優化,基本到位了,但我知道肯定還有可以改進的地方,請各路大神不惜賜教。

主要性能瓶頸還是在I/O上,就拿我自己的例子來說吧:

本機上用HHD存放MySQL和MSSQL數據庫,不管三七二之一,連同數據遷移程序也放在HHD。

一次讀寫5000條數據,單線程測試結果是:41分31秒

 

本機上創建一個RAM DISK用來存放MySQL和MSSQL數據庫,照舊,數據遷移程序也放在這里。

一次讀寫20W條數據,單線程測試結果:3分11秒

 

而改為ConcurrentQueue<T>多線程同步線程安全后,一次讀寫20W條數據,多線程測試結果:2分11秒

 

如果讀寫數據不需要按順序的話,完全可以拋棄掉ConcurrentQueue<T>,從而獲得更高的效率,更快的讀寫速度。

如果SqlBulkCopyOptions不設置為UseInternalTransaction (事務),又可以再快上一點點。

如果寫入目標是Oracle數據庫,和MSSQL相比,Oracle的平均寫入速度比MSSQL要快上0.1~0.35秒。

當然,無論怎樣,實際測試數據和我公布的測試數據是有差異的,畢竟使用環境不同。

這個測試結果并不專業,請各位多多見諒。

 

范例源碼https://gitcandy.com/Repository/Tree/MySQLToMSSQL-MultiThread-Queue-Safey

 

注釋:

FIFO:“先進先出法”是一種排程算法。它描述了一個佇列所使用的先到先得服務方式:先進入佇列的工作將先被完成,之后進來的則必須稍候。

參見英文版維基百科:http://en.wikipedia.org/wiki/FIFO_(computing)

中文版維基百科太簡潔了:http://zh.wikipedia.org/zh-cn/先進先出

 

HHD:全稱Hard Disk Drive,詳見:硬盤-百度百科

RAM Disk:詳見:RAM驅動器-百度百科


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()