当前位置: 首页 > 知识 >正文

实战手记:让百万级数据瞬间导入SQL Server

想必每个DBA都喜欢挑战数据导入时间。时间越短,工作效率越高,能充分证明他的实力。在实际工作中,有时需要将大量数据导入数据库,然后用于各种程序计算。

本文将推荐一个实验案例,挑战4秒钟的限制,并允许数百万数据立即导入sql server。

本实验将使用5中的方法来完成这一过程,并详细记录每种方法所花费的时间。使用的工具有visual studio 2008和sql server 2000,sql server 2008,

100万条数据分别通过方法5导入到SQL Server 2000和SQL Server 2008中。实验环境是具有2.0GCPU和2G内存的DELL 2850双服务器。

感兴趣的朋友可以下载源代码,自己验证时间。

好了,我们分别使用基本的Insert语句,BULK INSERT语句,多线程中的BULK INSERT,多线程中的SqlBulkCopy类和SqlBulkCopy类。

挑战4秒的极限。还有一点需要说明。在这个实验中,IsLine框架中的DataProvider模块用于执行SQL语句。这个模块只读取和封装SQL配置。

它不会对最终结果产生本质的影响。关于IsLine框架的框架知识,请参考“IsLine框架”系列文章。

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

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

这个方法是最基本的方法,大多数人一开始都会想到。但是Insert语句好像不太适合大规模操作吧?

该方法将100万条数据分为10批,每批包含10万条,每笔交易导入数据库10次。

-基本声明:

向TableB (Value1)中插入值(“I”);说明:语句中的I是宿主程序中的一个累加变量,用来填充数据库字段中的值。

SQL Server 2000耗时:901599

SQL Server 2008耗时:497638

方法二。使用BULK INSERT语句

这堂课的效果可以说是本次实验中最令人满意的。使用起来是最简单、最灵活、最快捷的。

“BULK INSERT”语句似乎并不常见。Aicken听说oracle中有一种方法,可以将外部文件映射到Oracle临时表中,然后将临时表中的数据直接导入到其他Oracle表中。

这种方法的速度非常令人满意。SQL SERVER的大容量插入同样令人满意吗?

-基本声明:

BULK INSERT TableB FROM '

c:\\sql.txt' WITH (FIELDTERMINATOR=',',ROWTER

/.mbMINATOR='|',BATCHSIZE=100000)

描述:“c:\\sql.txt”是一个预先生成的文件,包含100条数据,用“|”符号分隔,每100,000条数据有一个事务。

SQL Server 2000耗时:4009

SQL Server 2008耗时:10722

方法三。在多线程中使用批量插入。

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

SQL Server 2000耗时:21099

SQL Server 2008耗时:10997

方法四.使用SqlBulkCopy类

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

几千万条、多字段的数据的情况一般在一些业务场景中会遇到,比如计算全球消费者某个业务周期消费额时,要先获得主数据库表中的会员消费记录快照,并将快照储存至临时表中,然后供计算程序使用这些数据。

并且有些时候消费者的消费数据并不在一台数据库服务器中,而是来自多个国家的多台服务器,这样我们就必须借助内存或外存设备中转这些数据,然后清洗、合并、检测,最后导入专用表供计算程序使用。

基本语句:

using (System.Data.SqlClient.SqlBulkCopy sqlBC

=new System.Data.SqlClient.SqlBulkCopy(conn))

{ sqlBC.BatchSize=100000; sqlBC.BulkCopyTimeout

=60; 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 Server 2000耗时:4989

SQL Server 2008耗时:10412

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

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

SQL 2000耗时:7682

SQL 2008耗时:10870

结果

几天的时间终于把这个实验给完成了,比较令人失望的是SQL SERVER 2008导入数据的性能似乎并不想我们想象的那样优秀。

相关文章:
  • 7月12日基金净值:交银瑞和三年持有期混合最新净值0.8811,跌0.78%
  • 5月12日基金净值:博时央企创新驱动ETF最新净值1.3962,跌1.77%
  • 7天期逆回购利率迎10个月内首次下调,最新公募解读!鑫元基金:降息或将推高剩余流动性 短期看主题投资仍占优
  • 爆款基金运作满两年 首尾业绩相差近100%
  • 又有基金发行失败!年内66只基金清盘,创历史新高!公募行业"新陈代谢"提速_基金频道_证券之星
  • 7月14日基金净值:朱雀恒心一年持有混合最新净值0.8405,跌0.38%
  • 5月30日基金净值:工银招瑞一年持有混合A最新净值0.9731,涨0.03%
  • 6月26日基金净值:光大健康优加混合A最新净值0.7411,跌1.09%
  • 5月19日基金净值:汇安多因子混合A最新净值1.4935,涨0.33%
  • 4月3日基金净值:创金合信工业周期股票A最新净值2.434,涨1.21%_基金频道_证券之星