.Net Core导入千万级数据至Mysql的步骤


Posted in MySQL onMay 24, 2021

前期准备

订单测试表

CREATE TABLE `trade` (
  `id` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
  `trade_no` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8_unicode_ci',
  UNIQUE INDEX `id` (`id`),
  INDEX `trade_no` (`trade_no`)
)
COMMENT='订单'
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB;

测试环境

操作系统:Window 10 专业版

CPU:Inter(R) Core(TM) i7-8650U CPU @1.90GHZ 2.11 GHZ

内存:16G

MySQL版本:5.7.26

实现方法:

1、单条数据插入

这是最普通的方式,通过循环一条一条的导入数据,这个方式的缺点很明显就是每一次都需要连接一次数据库。

 实现代码:

//开始时间
var startTime = DateTime.Now;
using (var conn = new MySqlConnection(connsql))
{
    conn.Open();
​
    //插入10万数据
    for (var i = 0; i < 100000; i++)
    {
        //插入
        var sql = string.Format("insert into trade(id,trade_no) values('{0}','{1}');",
            Guid.NewGuid().ToString(), "trade_" + (i + 1)
            );
        var sqlComm = new MySqlCommand();
        sqlComm.Connection = conn;
        sqlComm.CommandText = sql;
        sqlComm.ExecuteNonQuery();
        sqlComm.Dispose();
    }
​
    conn.Close();
}
​
//完成时间
var endTime = DateTime.Now;
​
//耗时
var spanTime = endTime - startTime;
Console.WriteLine("循环插入方式耗时:" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");

10万条测试耗时:

.Net Core导入千万级数据至Mysql的步骤

上面的例子,我们是批量导入10万条数据,需要连接10万次数据库。我们把SQL语句改为1000条拼接为1条,这样就能减少数据库连接,实现代码修改如下:

//开始时间
var startTime = DateTime.Now;
using (var conn = new MySqlConnection(connsql))
{
    conn.Open();
​
    //插入10万数据
    var sql = new StringBuilder();
    for (var i = 0; i < 100000; i++)
    {
        //插入
        sql.AppendFormat("insert into trade(id,trade_no) values('{0}','{1}');",
            Guid.NewGuid().ToString(), "trade_" + (i + 1)
            );
​
        //合并插入
        if (i % 1000 == 999)
        {
            var sqlComm = new MySqlCommand();
            sqlComm.Connection = conn;
            sqlComm.CommandText = sql.ToString();
            sqlComm.ExecuteNonQuery();
            sqlComm.Dispose();
            sql.Clear();
        }
    }
​
    conn.Close();
}
​
//完成时间
var endTime = DateTime.Now;
​
//耗时
var spanTime = endTime - startTime;
Console.WriteLine("循环插入方式耗时:" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");

10万条测试耗时:

.Net Core导入千万级数据至Mysql的步骤

通过优化后,原本需要10万次连接数据库,只需连接100次。从最终运行效果看,由于数据库是在同一台服务器,不涉及网络传输,性能提升不明显。

2、合并数据插入

在MySQL同样也支持,通过合并数据来实现批量数据导入。实现代码:

//开始时间
var startTime = DateTime.Now;
using (var conn = new MySqlConnection(connsql))
{
    conn.Open();
​
    //插入10万数据
    var sql = new StringBuilder();
    for (var i = 0; i < 100000; i++)
    {
        if (i % 1000 == 0)
        {
            sql.Append("insert into trade(id,trade_no) values");
        }
​
        //拼接
        sql.AppendFormat("('{0}','{1}'),", Guid.NewGuid().ToString(), "trade_" + (i + 1));
​
        //一次性插入1000条
        if (i % 1000 == 999)
        {
            var sqlComm = new MySqlCommand();
            sqlComm.Connection = conn;
            sqlComm.CommandText = sql.ToString().TrimEnd(',');
            sqlComm.ExecuteNonQuery();
            sqlComm.Dispose();
            sql.Clear();
        }
    }
        
​
    conn.Close();
}
​
//完成时间
var endTime = DateTime.Now;
​
//耗时
var spanTime = endTime - startTime;
Console.WriteLine("合并数据插入方式耗时:" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");

10万条测试耗时:

.Net Core导入千万级数据至Mysql的步骤

通过这种方式插入操作明显能够提高程序的插入效率。虽然第一种方法通过优化后,同样的可以减少数据库连接次数,但第二种方法:合并后日志量(MySQL的binlog和innodb的事务让日志)减少了,降低日志刷盘的数据量和频率,从而提高效率。同时也能减少SQL语句解析的次数,减少网络传输的IO。

3、MySqlBulkLoader插入

MySQLBulkLoader也称为LOAD DATA INFILE,它的原理是从文件读取数据。所以我们需要将我们的数据集保存到文件,然后再从文件里面读取。

实现代码:

//开始时间
var startTime = DateTime.Now;
using (var conn = new MySqlConnection(connsql))
{
    conn.Open();
    var table = new DataTable();
    table.Columns.Add("id", typeof(string));
    table.Columns.Add("trade_no", typeof(string));
​
    //生成10万数据
    for (var i = 0; i < 100000; i++)
    {
        if (i % 500000 == 0)
        {
            table.Rows.Clear();
        }
​
        //记录
        var row = table.NewRow();
        row[0] = Guid.NewGuid().ToString();
        row[1] = "trade_" + (i + 1);
        table.Rows.Add(row);
​
        //50万条一批次插入
        if (i % 500000 != 499999 && i < (100000 - 1))
        {
            continue;
        }
        Console.WriteLine("开始插入:" + i);
​
        //数据转换为csv格式
        var tradeCsv = DataTableToCsv(table);
        var tradeFilePath = System.AppDomain.CurrentDomain.BaseDirectory + "trade.csv";
        File.WriteAllText(tradeFilePath, tradeCsv);
​
        #region 保存至数据库
        var bulkCopy = new MySqlBulkLoader(conn)
        {
            FieldTerminator = ",",
            FieldQuotationCharacter = '"',
            EscapeCharacter = '"',
            LineTerminator = "\r\n",
            FileName = tradeFilePath,
            NumberOfLinesToSkip = 0,
            TableName = "trade"
        };
​
        bulkCopy.Columns.AddRange(table.Columns.Cast<DataColumn>().Select(colum => colum.ColumnName).ToList());
        bulkCopy.Load();
        #endregion
    }
​
    conn.Close();
}
​
//完成时间
var endTime = DateTime.Now;
​
//耗时
var spanTime = endTime - startTime;
Console.WriteLine("MySqlBulk方式耗时:" + spanTime.Minutes + "分" + spanTime.Seconds + "秒" + spanTime.Milliseconds + "毫秒");

10万条测试耗时:

.Net Core导入千万级数据至Mysql的步骤

注意:MySQL数据库配置需开启:允许文件导入。配置如下:

secure_file_priv= 

性能测试对比

针对上面三种方法,分别测试10万、20万、100万、1000万条数据记录,最终性能入如下:

.Net Core导入千万级数据至Mysql的步骤

最后

通过测试数据看,随着数据量的增大,MySqlBulkLoader的方式表现依旧良好,其他方式性能下降比较明显。MySqlBulkLoader的方式完全可以满足我们的需求。

以上就是.Net Core导入千万级数据至Mysql的步骤的详细内容,更多关于导入千万级数据至Mysql的资料请关注三水点靠木其它相关文章!

MySQL 相关文章推荐
mysql多表查询-笔记七
Apr 05 MySQL
MySQL的join buffer原理
Apr 29 MySQL
MySQL REVOKE实现删除用户权限
Jun 18 MySQL
VS2019连接MySQL数据库的过程及常见问题总结
Nov 27 MySQL
Mysql外键约束的创建与删除的使用
Mar 03 MySQL
MySQL如何快速创建800w条测试数据表
Mar 17 MySQL
你真的会用Mysql的explain吗
Mar 31 MySQL
mysql使用 not int 子查询隐含陷阱
Apr 12 MySQL
MySql分区类型及创建分区的方法
Apr 13 MySQL
MySQL分区以及建索引的方法总结
Apr 13 MySQL
MySQL实现字段分割一行转多行的示例代码
Jul 07 MySQL
MySQL 原理与优化之Limit 查询优化
Aug 14 MySQL
MySQL大小写敏感的注意事项
May 24 #MySQL
MySQL 使用事件(Events)完成计划任务
May 24 #MySQL
MySQL触发器的使用
May 24 #MySQL
MySQL 重命名表的操作方法及注意事项
May 21 #MySQL
Mysql官方性能测试工具mysqlslap的使用简介
May 21 #MySQL
MySQL官方导出工具mysqlpump的使用
May 21 #MySQL
新手必备之MySQL msi版本下载安装图文详细教程
You might like
全国FM电台频率大全 - 23 四川省
2020/03/11 无线电
JAVA/JSP学习系列之六
2006/10/09 PHP
解析php下载远程图片函数 可伪造来路
2013/06/25 PHP
php网页标题中文乱码的有效解决方法
2014/03/05 PHP
跟我学Laravel之快速入门
2014/10/15 PHP
php实现微信公众号企业转账功能
2018/10/01 PHP
js 页面输出值
2008/11/30 Javascript
基于JQuery实现滚动到页面底端时自动加载更多信息
2014/01/31 Javascript
nodejs中实现路由功能
2014/12/29 NodeJs
JavaScript实现鼠标点击后层展开效果的方法
2015/05/13 Javascript
基于jQuery+PHP+Mysql实现在线拍照和在线浏览照片
2015/09/06 Javascript
JavaScript文档碎片操作实例分析
2015/12/12 Javascript
使用JS实现图片展示瀑布流效果的实例代码
2016/09/12 Javascript
使用JS读取XML文件的方法
2016/11/25 Javascript
node.js入门教程之querystring模块的使用方法
2017/02/27 Javascript
Mac系统下Webstorm快捷键整理大全
2017/05/28 Javascript
vue项目中使用fetch的实现方法
2019/04/25 Javascript
微信小程序使用websocket通讯的demo,含前后端代码,亲测可用
2019/05/22 Javascript
vue vantUI实现文件(图片、文档、视频、音频)上传(多文件)
2019/10/15 Javascript
Electron整合React使用搭建开发环境的步骤详解
2020/06/07 Javascript
pyqt4教程之实现半透明的天气预报界面示例
2014/03/02 Python
windows上安装python3教程以及环境变量配置详解
2019/07/18 Python
使用keras2.0 将Merge层改为函数式
2020/05/23 Python
Python调用.net动态库实现过程解析
2020/06/05 Python
CSS3支持IE6, 7, and 8的边框border属性
2012/12/28 HTML / CSS
使用CSS3的::selection改变选中文本颜色的方法
2015/09/29 HTML / CSS
移动端HTML5实现文件上传功能【附代码】
2016/03/25 HTML / CSS
Clarks鞋澳大利亚官方网站:Clarks Australia
2019/12/25 全球购物
美国价格实惠的在线眼镜网站:Zeelool
2020/12/25 全球购物
中学教师师德师风演讲稿
2014/08/22 职场文书
初中国旗下的演讲稿
2014/08/28 职场文书
小学生勤俭节约演讲稿
2014/08/28 职场文书
党员批评与自我批评范文
2014/09/23 职场文书
2014年会计个人工作总结
2014/11/24 职场文书
python调试工具Birdseye的使用教程
2021/05/25 Python
详解Laravel框架的依赖注入功能
2021/05/27 PHP