作者: Aicken(李鸣)  来源: 博客园  发布时间: 2010-09-08 15:00  阅读: 4520 次  推荐: 0                   原文链接   [收藏]

摘要:实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方法所耗费的时间。

  本实验中所用到工具为VS2008和SQL SERVER 2000、SQL SERVER 2008,分别使用5中方法将100万条数据导入SQL 2000与SQL 2008中,实验环境是DELL 2850双2.0GCPU,2G内存的服务器。感兴趣的朋友可以下载源代码自己验证一下所用时间。

  还要有一点需要进行说明,本实验中执行SQL语句的地方使用了IsLine FrameWork框架中的DataProvider模块,这个模块只是对SQL配置的读取和封装,并不会对最终结果有本质性的影响,关于IsLine FrameWork框架方面的知识,请参考“IsLine FrameWork”框架系列文章。

  下面进入正题,分别使用基本的Insert 语句、使用BULK INSERT语句、在多线程中使用BULK INSERT、使用SqlBulkCopy类、在多线程中使用SqlBulkCopy类五种方法,挑战4秒极限。

  数据库方面使用SQL 2000与SQL 2008,表名TableB,字段名称为Value1,数据库名可以在App.config中修改,默认为test。

图 1 试验中的5种方法

  方法一.使用基本的Insert 语句

  这种方法是最基本的方法,大多数人一开始都会想到这种方法。但是Insert语句似乎并不适合大批量的操作,是不是这样呢?

  本方法中将100万数据分为10个批次,每个批次10万条,每10万条1个事务,分10次导入数据库。

  基本语句:Insert Into TableB (Value1) values (‘”+i+”’);

  说明:语句中的i是宿主程序中的一个累加变量,用于填充数据库字段中的值。

  SQL 2000 耗时:901599

  SQL 2008耗时:497638

  方法二.使用BULK INSERT语句

  这个类的效果,在本实验中可以说是最令人满意的了,它的使用最简便、灵活,速度很快。

  “BULK INSERT”语句似乎不是很常用, Aicken听说Oracle中有一种可以将外部文件映射为Oracle临时表,然后直接将临时表中的数据导入Oracle其他表中的方法,这种方法的速度非常令人满意,SQL SERVER的BULK INSERT是不是同样令人满意呢?

  基本语句:BULK INSERT TableB FROM 'c:\\sql.txt' WITH (FIELDTERMINATOR = ',',ROWTER /.,mbMINATOR='|',BATCHSIZE = 100000)

  说明:“c:\\sql.txt”是一个预先生成的包含100条数据的文件,这些数据以“|”符号分隔,每10万条数据一个事务。

  SQL 2000耗时:4009

  SQL 2008耗时:10722

  方法三.在多线程中使用BULK INSERT

  在方法二的基础上,将100万条数据分五个线程,每个线程负责20万条数据,每5万条一个事物,五个线程同时启动,看看这样的效果吧。

  SQL 2000耗时:21099

  SQL 2008耗时:10997

  方法四.使用SqlBulkCopy类

  这种方法速度也很快,但是要依赖内存,对于几千万条、多字段的复杂数据,可能在内存方面会有较大的消耗,不过可以使用64位解决方案处理这个问题。

  几千万条、多字段的数据的情况一般在一些业务场景中会遇到,比如计算全球消费者某个业务周期消费额时,要先获得主数据库表中的会员消费记录快照,并将快照储存至临时表中,然后供计算程序使用这些数据。并且有些时候消费者的消费数据并不在一台数据库服务器中,而是来自多个国家的多台服务器,这样我们就必须借助内存或外存设备中转这些数据,然后清洗、合并、检测,最后导入专用表供计算程序使用。

  基本语句:

using (System.Data.SqlClient.SqlBulkCopy sqlBC =new System.Data.SqlClient.SqlBulkCopy(conn)) { sqlBC.BatchSize =; sqlBC.BulkCopyTimeout =; sqlBC.DestinationTableName ="dbo.TableB"; sqlBC.ColumnMappings.Add("valueA", "Value1"); sqlBC.WriteToServer(dt); }

  说明:

  BatchSize = 100000; 指示每10万条一个事务并提交

  BulkCopyTimeout = 60; 指示60秒按超时处理

  DestinationTableName = "dbo.TableB"; 指示将数据导入TableB表

  ColumnMappings.Add("valueA", "Value1"); 指示将内存中valueA字段与TableB中的Value1字段匹配

  WriteToServer(dt);写入数据库。其中dt是预先构建好的DataTable,其中包含valueA字段。

  SQL 2000耗时:4989

  SQL 2008耗时:10412

  方法五.在多线程中使用SqlBulkCopy类

  基于方法四,将100万条数据分五个线程,每个线程负责20万条数据,每5万条一个事物,五个线程同时启动,看看这样的效果吧。

  SQL 2000耗时:7682

  SQL 2008耗时:10870

  总结

数据库测试方式

SQL 2000

SQL 2008

基本Insert Into

901599

497638

单线程Bulk Insert

4209

10722

多线程Bulk Insert

21099

10997

单线程SqlBulkCopy

4989

10412

多线程SqlBulkCopy

7682

10870

  以上就是这几天的实验结果了,比较令人失望的是SQL SERVER 2008导入数据的性能似乎并不想我们想象的那样优秀。

  另外,有下载源代码的帮我看看,为什么多线程的成绩还不如单线程的优秀呢?是静态资源使用不当造成的,还是其他什么原因?

  源码地址:http://files.cnblogs.com/isline/sqltest.rar

  测试数据下载地址:http://files.cnblogs.com/isline/Data.rar

C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)的更多相关文章

  1. 极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)

    原文:极限挑战-C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方 ...

  2. 极限挑战—C#+ODP 100万条数据导入Oracle数据库仅用不到1秒

    链接地址:http://www.cnblogs.com/armyfai/p/4646213.html 要:在这里我们将看到的是C#中利用ODP实现在Oracle数据库中瞬间导入百万级数据,这对快速批量 ...

  3. Excel表数据导入Sql Server数据库中

    Excel表数据导入Sql Server数据库的方法很多,这里只是介绍了其中一种: 1.首先,我们要先在test数据库中新建一个my_test表,该表具有三个字段tid int类型, tname nv ...

  4. 教你如何6秒钟往MySQL插入100万条数据!然后删库跑路!

    教你如何6秒钟往MySQL插入100万条数据!然后删库跑路! 由于我用的mysql 8版本,所以增加了Timezone,然后就可以了 前提是要自己建好库和表. 数据库test, 表user, 三个字段 ...

  5. Qt中提高sqlite的读写速度(使用事务一次性写入100万条数据)

    SQLite数据库本质上来讲就是一个磁盘上的文件,所以一切的数据库操作其实都会转化为对文件的操作,而频繁的文件操作将会是一个很好时的过程,会极大地影响数据库存取的速度.例如:向数据库中插入100万条数 ...

  6. shell awk处理过滤100万条数据

    背景: 100万条数据.格式如下: ID 地址 1895756546931805 安徽省六安市裕安区固镇镇佛俺村柳树队5758 安徽省蒙城县岳坊镇胡寨村小组小胡寨庄6号 183494167409969 ...

  7. Excel文件导入SQL Server数据库

    Excel表格的使用可谓是非常广泛,博主也简单百度了一下Excel的发展. 发展历程: 1982年 Microsoft推出了它的第一款电子制表软件-Multiplan,并在CP/M系统上大 Excel ...

  8. 将DataTable 数据插入 SQL SERVER 数据库

    原文:将DataTable 数据插入 SQL SERVER 数据库 以下提供3中方式将DataTable中的数据插入到SQL SERVER 数据库: 一:使用sqlcommand.executenon ...

  9. 1000万条数据导入mysql

    今天需要将一个含有1000万条数据的文本内容插入到数据库表中,最初自然想到的是使用Insertinto '表名'values(),(),()...这种插入方式,但是发现这种方式对1000万条数据量的情 ...

随机推荐

  1. Linux挂在ntfs格式的U盘

    工作中遇到linux系统 Red Hat Enterprise5.7 挂载希捷ntfs格式移动硬盘,会跳出一个ERROR提示框:The volume ‘EAGET-NQH’user the ntfs ...

  2. (简单) LightOJ 1074 Extended Traffic,SPFA+负环。

    Description Dhaka city is getting crowded and noisy day by day. Certain roads always remain blocked ...

  3. NULL、nil、Nil、NSNull的区别

    标志 值 含义 NULL (void *)0 C指针的字面零值 nil (id)0 Objecve-C对象的字面零值 Nil (Class)0 Objecve-C类的字面零值 NSNull [NSNu ...

  4. MySQL中 InnoDB 和 MyISAM 小结

    转:http://blog.csdn.net/ithomer/article/details/5136982 部分内容: InnoDB和MyISAM的差别 InnoDB和MyISAM是许多人在使用My ...

  5. iOS 将NSArray、NSDictionary转换为JSON格式进行网络传输

    http://blog.csdn.net/worldzhy/article/details/49982491 将NSArray.NSDictionary转换为JSON格式进行网络传输,是经常用到的,但 ...

  6. mysql数据库中间件研究

    随着互联网的发展,数据量的不断增大. 单台实例已经远远无法满足业务的需要. 对数据库分库分表的需求不断的增加随之而来的就是数据库中间件的开发. 一. 单台实例主要面临下面几个问题: 1.  数据量太大 ...

  7. 史上最坑的证书报错解决方法:Code=3000 "未找到应用程序的“aps-environment”的权利字符串"

    在ios注册远程通知获取设备令牌token的时候 // 注册远程通知获取设备令牌 toKen [[ UIApplication sharedApplication ] registerForRemot ...

  8. ul中li分列显示

    让ul中li分列显示,用li显示两列如下(要显视多列的自己想办法,哈哈): 2列 <ul> <li style="display:block;float:left;widt ...

  9. 数字(数学)操作类 Math Random 类 ,大数字操作类

    Math 提供了大量的数学操作方法 Math类中所有的方法都是static 方法

  10. UVa 908 - Re-connecting Computer Sites

    题目大意:有n个网站,由m条线路相连,每条线路都有一定的花费,找出连接所有线路的最小花费. 最小生成树问题(Minimal Spanning Tree, MST),使用Kruskal算法解决. #in ...