這里采用.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驅動器-百度百科
文章列表