视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
MySQL数据迁移到MSSQL-以小米数据库为例-测试828W最快可达到2分1_MySQL
2020-11-09 19:20:25 责编:小采
文档


这里采用.NET Framework 4.0以上版本中新出现的 ConcurrentQueue

MSDN是这样描述的:

ConcurrentQueue类是一个线程安全的先进先出 (FIFO) 集合。

ConcurrentQueue的所有公共且受保护的成员都是线程安全的,可从多个线程同时使用。

共采用两个线程,一个读一个写。

ConcurrentQueue的实现方法:

(FIFO) 集合:

ConcurrentQueue DataTableList = new ConcurrentQueue();

读:

 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多线程同步线程安全后,一次读写20W条数据,多线程测试结果:2分11秒

如果读写数据不需要按顺序的话,完全可以抛弃掉ConcurrentQueue,从而获得更高的效率,更快的读写速度。

如果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驱动器-百度百科

下载本文
显示全文
专题