准备条件:20万+数据

界面设计使用的WPF。

没有对比就没有伤害,以下是我两种方式导入数据案例。

运行 结果对比:

首先使用一般sql语句导入,因为时间原因,我就没有等待程序执行完,但是我记录了大约需要多少时间,以及执行了多少时间。
导入数据共计:258113条,执行了38秒,已经入库了6971条,大约还需要1429秒。(不去考虑电脑配置,界面数据加载耗时等因素)

接下来我们看看同样的数据量 SqlBulkCopy效果如何:

当我注释代码中使用异步操作,当然,界面会出现假死状态。再来看看运行结果。

解析数据时间明显减少。

以下是这个测试工具的全部代码:

    /// <summary>
/// BatchImportForm.xaml 的交互逻辑
/// </summary>
public partial class BatchImportForm : Window
{
private static readonly string ConnStr = ConfigurationManager.ConnectionStrings["myconnStr"].ConnectionString;
public BatchImportForm()
{
InitializeComponent();
} private void BtnQueryImport_Click(object sender, RoutedEventArgs e)
{
var filePath = GetFilePath();
if (!string.IsNullOrEmpty(filePath))
{
// 防止界面假死状态
Task task = Task.Factory.StartNew(() =>
{
SqlWork(filePath);
});
}
} private string GetFilePath()
{
// 读取文本文件
OpenFileDialog ofd = new OpenFileDialog();
ofd.InitialDirectory = System.Environment.CurrentDirectory+ "\\Resources\\Txt"; // @"C:\Users\WenDaoJun\Documents\Visual Studio 2015\Projects\JWell\JWell.Cloud.UI\Resources\Txt";
ofd.Title = "读取文件";
ofd.FileName = "";
ofd.RestoreDirectory = true;
ofd.Filter = "所有文件(*.*)|*.*|文本文件(*.txt)|*.txt";
ofd.ValidateNames = true;
ofd.CheckFileExists = true;
ofd.CheckPathExists = true;
string strName = string.Empty;
if (ofd.ShowDialog() == true)
{
strName = ofd.FileName;
}
if (strName == "")
{
MessageBox.Show("没有选择文件!");
return null;
}
return strName;
} private void BtnQueryImportTwo_Click(object sender, RoutedEventArgs e)
{
string filePath = GetFilePath();
//if (!string.IsNullOrEmpty(filePath))
//{
// Task task = Task.Factory.StartNew(() =>
// {
// SqlBulkWord(filePath);
// }); //}
SqlBulkWord(filePath);
} /// <summary>
/// 第一种方法
/// </summary>
/// <param name="fuillPath"></param>
private void SqlWork(string fuillPath)
{
var lines = File.ReadAllLines(fuillPath, Encoding.Default);
// 异步给控件赋值
this.Dispatcher.Invoke(() => { this.JingDuOn.Maximum = lines.Length; });
this.Dispatcher.Invoke(() => { this.LblRuKuOne.Content = lines.Length; });
using (SqlConnection conn = new SqlConnection(ConnStr))
{
conn.Open();
var t1 = DateTime.Now;
for (int i = ; i < lines.Length; i++)
{
// 拼接数据
// 解析文本文件 "\"号段\"\t\"所属地区\"\t\"号码类型\"\t\"区号\""
var strs = lines[i].Split('\t');
var telNumber = strs[].Trim('"');
var telArea = strs[].Trim('"');
var telType = strs[].Trim('"');
var telAreaCode = strs[].Trim('"');
// 入库
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = @"insert into TelNum(TelNumber,TelType,TelArea,TelAreaCode) values(@TelNumber,@TelType,@TelArea,@TelAreaCode)";
cmd.Parameters.Add(new SqlParameter("@TelNumber", telNumber));
cmd.Parameters.Add(new SqlParameter("@TelType", telArea));
cmd.Parameters.Add(new SqlParameter("@TelArea", telType));
cmd.Parameters.Add(new SqlParameter("@TelAreaCode", telAreaCode));
cmd.ExecuteNonQuery();
//异步委托
this.JingDuOn.Dispatcher.Invoke(() => { this.JingDuOn.Value += ; });
this.LblJinDuOne.Dispatcher.Invoke(() => { this.LblJinDuOne.Content = i; });
}
var t2 = DateTime.Now;
var tsp = t2 - t1;
// 异步给控件赋值
this.LblHaoShiOne.Dispatcher.Invoke(() => { this.LblHaoShiOne.Content = tsp.TotalSeconds; });
this.LblZongHaoShiOne.Dispatcher.Invoke(() => { this.LblZongHaoShiOne.Content = $"倒计时{(tsp.TotalSeconds * lines.Length / (i + 1))}秒完成。"; });
} }
} /// <summary>
/// 第二种方法
/// </summary>
/// <param name="filePath"></param>
private void SqlBulkWord(string filePath)
{
var lines = File.ReadAllLines(filePath, Encoding.Default);
this.Dispatcher.Invoke(() => { this.JingDuTwo.Maximum = lines.Length; });
this.Dispatcher.Invoke(() => { this.LblRuKuTwo.Content = lines.Length; });
var t1 = DateTime.Now; // 创建入库需要的数据源 DataTable
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("TelNumber", typeof(string)));
dt.Columns.Add(new DataColumn("TelType", typeof(string)));
dt.Columns.Add(new DataColumn("TelArea", typeof(string)));
dt.Columns.Add(new DataColumn("TelAreaCode", typeof(string))); for (int i = ; i < lines.Length; i++)
{
var row = dt.NewRow();
// 拼接数据
// 解析文本文件 "\"号段\"\t\"所属地区\"\t\"号码类型\"\t\"区号\""
var strs = lines[i].Split('\t');
row["TelNumber"] = strs[].Trim('"');
row["TelType"] = strs[].Trim('"');
row["TelArea"] = strs[].Trim('"');
row["TelAreaCode"] = strs[].Trim('"');
dt.Rows.Add(row); this.JingDuTwo.Dispatcher.Invoke(() => { this.JingDuTwo.Value += ; });
this.LblJinDuTwo.Dispatcher.Invoke(() => { this.LblJinDuTwo.Content = i; }); }
var t2 = DateTime.Now;
var tsp = t2 - t1;
this.LblHaoShiTwo.Dispatcher.Invoke(() => { this.LblHaoShiTwo.Content = tsp.TotalSeconds; }); // 入库计时
var sw = new Stopwatch();
sw.Start();
using (SqlBulkCopy sbk = new SqlBulkCopy(ConnStr))
{
//表名
sbk.DestinationTableName = "TelNum";
//DataTable中的列名和数据库中列名对应
sbk.ColumnMappings.Add("TelNumber", "TelNumber");
sbk.ColumnMappings.Add("TelType", "TelType");
sbk.ColumnMappings.Add("TelArea", "TelArea");
sbk.ColumnMappings.Add("TelAreaCode", "TelAreaCode");
sbk.WriteToServer(dt);
}
sw.Stop(); this.LblZongHaoShiTwo.Dispatcher.Invoke(() => { this.LblZongHaoShiTwo.Content=sw.Elapsed.TotalSeconds; }); }
}

C# SqlBulkCopy数据批量入库的更多相关文章

  1. discuz数据批量入库接口

    近期在做社区,首选discuz,数据需要用scrapy爬虫批量入库,就写了一个php入库接口. <?php define('PW', 'abc123456');//一定要修改 if($_REQU ...

  2. C# SqlBulkCopy类批量导入数据

    特别注意  sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); 插入的时候列的顺序可 ...

  3. SqlBulkCopy将DataTable中的数据批量插入数据库中

    #region 使用SqlBulkCopy将DataTable中的数据批量插入数据库中 /// <summary> /// 注意:DataTable中的列需要与数据库表中的列完全一致.// ...

  4. list转datatable,SqlBulkCopy将DataTable中的数据批量插入数据库

    /// <summary> /// 将泛类型集合List类转换成DataTable /// </summary> /// <param name="list&q ...

  5. DataTable数据批量写入数据库三种方法比较

    DataTable数据批量写入数据库三种方法比较 标签: it 分类: C#1)   insert循环插入:2)   sqldataadapter.update(dataset,tablename); ...

  6. 【hbase】——HBase 写优化之 BulkLoad 实现数据快速入库

    1.为何要 BulkLoad 导入?传统的 HTableOutputFormat 写 HBase 有什么问题? 我们先看下 HBase 的写流程: 通常 MapReduce 在写HBase时使用的是 ...

  7. 高并发简单解决方案————redis队列缓存+mysql 批量入库(ThinkPhP)

    问题分析 问题一:要求日志最好入库:但是,直接入库mysql确实扛不住,批量入库没有问题,done.[批量入库和直接入库性能差异] 问题二:批量入库就需要有高并发的消息队列,决定采用redis lis ...

  8. 转载:【高并发简单解决方案 | 靠谱崔小拽 】redis队列缓存 + mysql 批量入库 + php离线整合

    需求背景:有个调用统计日志存储和统计需求,要求存储到mysql中:存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮. 问题分析 思考:应用网站架构的衍化过程中,应用最新的框 ...

  9. C#中几种数据库的大数据批量插入

    C#语言中对SqlServer.Oracle.SQLite和MySql中的数据批量插入是支持的,不过Oracle需要使用Orace.DataAccess驱动. IProvider里有一个用于实现批量插 ...

随机推荐

  1. 修改GDAL库支持RPC像方改正模型

    最近在做基于RPC的像方改正模型,方便对数据进行测试,修改了GDAL库中的RPC纠正模型,使之可以支持RPC像方改正参数. 下面是RPC模型的公式,rn,cn为归一化之后的图像行列号坐标,PLH为归一 ...

  2. pig的cogroup详解

    从实例出发 %default file test.txt A = load '$file' as (date, web, name, food); B = load '$file' as (date, ...

  3. webview与js交互

     对于android初学者应该都了解webView这个组件.之前我也是对其进行了一些简单的了解,但是在一个项目中不得不用webview的时候,发现了webview的强大之处,今天就分享一下使用we ...

  4. listview优化(中)

    1,对Imageview使用setTag()方法来解决图片错位问题,这个Tag中设置的是图片的url,然后在加载的时候取得这个url和要加载那position中的url对比,如果不相同就加载,相同就是 ...

  5. C#之委托和事件

    我想,读者们可能看过一部电影叫<全民目击>,在电影中,富豪林泰婚期将至,准新娘却惨死地下停车场,林泰的富二代女儿林萌萌成为最大嫌疑人,林泰不惜重金聘请国内顶级律师周莉为女儿辩护,而公诉方却 ...

  6. 使用API获取(默认付款条件和到期日)

    1. 目的:使用API取到应收事务处理的付款条件(实现标准功能的付款条件和到期日)2. 实现方法:调用 ARP_TRX_DEFAULTS_3.get_term_default获得付款条件 3.实现代码 ...

  7. nodejs书籍

    http://product.dangdang.com/23371791.html#catalog https://www.byvoid.com/project/node http://www.ama ...

  8. Android 几种网络请求的区别与联系

    HttpUrlConnection 最开始学android的时候用的网络请求是HttpUrlConnection,当时很多东西还不知道,但是在android 2.2及以下版本中HttpUrlConne ...

  9. Spring--ClassPathResource

    /* * 用一个给定的类加载器或者给定的类来加载资源 */ public class ClassPathResource extends AbstractFileResolvingResource { ...

  10. 收集一些dos网络配置命令,从新获取ip刷新dns

    今天台式机插着无线网卡连接学校无线网,结果就要登录了,完后ip地址固定半天,换了mac地址重新分配还是不能改,ping了主机也不通,我想可能是dns没有刷新.现在收集几个dos命令用来配置网络: 1. ...