.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 可扩展设计的基本原则
May 14 MySQL
my.ini优化mysql数据库性能的十个参数(推荐)
May 26 MySQL
解决Navicat for Mysql连接报错1251的问题(连接失败)
May 27 MySQL
MySQL 8.0 驱动与阿里druid版本兼容问题解决
Jul 01 MySQL
MySQL系列之十一 日志记录
Jul 02 MySQL
mysql定时自动备份数据库的方法步骤
Jul 07 MySQL
MySQL分库分表详情
Sep 25 MySQL
Mysql数据库手动及定时备份步骤
Nov 07 MySQL
mysql中整数数据类型tinyint详解
Dec 06 MySQL
MySQL8.0 Undo Tablespace管理详解
Jun 16 MySQL
mysql幻读详解实例以及解决办法
Jun 16 MySQL
MySQL主从切换的超详细步骤
Jun 28 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
PHP一些有意思的小区别
2006/12/06 PHP
PHP第一季视频教程(李炎恢+php100 不断更新)
2011/05/29 PHP
php计算两个日期时间差(返回年、月、日)
2014/06/19 PHP
php采用session实现防止页面重复刷新
2015/12/24 PHP
基于jquery的Repeater实现代码
2010/07/17 Javascript
5个javascript的数字格式化函数分享
2011/12/07 Javascript
JavaScript数据结构与算法之链表
2016/01/29 Javascript
js实现不重复导入的方法
2016/03/02 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
vue.js初学入门教程(2)
2016/11/07 Javascript
微信小程序教程系列之视图层的条件渲染(10)
2017/04/19 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
js模块加载方式浅析
2017/08/12 Javascript
基于JavaScript实现带数据验证和复选框的表单提交
2017/08/23 Javascript
微信小程序使用form表单获取输入框数据的实例代码
2018/05/17 Javascript
在Vue methods中调用filters里的过滤器实例
2018/08/30 Javascript
js实现随机点名器精简版
2020/06/29 Javascript
Python中实现参数类型检查的简单方法
2015/04/21 Python
pandas 获取季度,月度,年度首尾日期的方法
2018/04/11 Python
Python计算一个给定时间点前一个月和后一个月第一天的方法
2018/05/29 Python
对Pandas MultiIndex(多重索引)详解
2018/11/16 Python
Python实现的线性回归算法示例【附csv文件下载】
2018/12/29 Python
python读取csv和txt数据转换成向量的实例
2019/02/12 Python
opencv python 图像轮廓/检测轮廓/绘制轮廓的方法
2019/07/03 Python
flask实现验证码并验证功能
2019/12/05 Python
sklearn+python:线性回归案例
2020/02/24 Python
Pycharm远程连接服务器并实现代码同步上传更新功能
2020/02/25 Python
python能做哪方面的工作
2020/06/15 Python
Visual Studio code 配置Python开发环境
2020/09/11 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
2020/11/06 Python
什么是ESB?请介绍一下ESB?
2015/05/27 面试题
数控专业推荐信范文
2013/12/02 职场文书
高中运动会广播稿
2014/01/21 职场文书
《三亚落日》教学反思
2014/04/26 职场文书
广告宣传策划方案
2014/05/21 职场文书
使用springboot暴露oracle数据接口的问题
2021/05/07 Oracle