• MySQL数据迁移到MSSQL-以小米数据库为例-测试828W最快可达到2分11秒


    这里采用.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}	{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驱动器-百度百科

  • 相关阅读:
    Hive 2.1.1安装配置
    vi / vim 删除以及其它命令
    『MySQL』时间戳转换
    update 中实现子查询
    hive lateral view 与 explode详解
    xpath定位方法详解
    Python int与string之间的转化
    ORM、SQLAchemy
    python bottle 简介
    python wsgi 简介
  • 原文地址:https://www.cnblogs.com/VAllen/p/MySQLToMSSQL-MultiThread-Queue-Safey.html
Copyright © 2020-2023  润新知