2012-03-06 84 views
1

有大约这里400 MB .txt文件由分隔插入数据“|”。在C#中使用Windows窗体,我将.txt文件的每一行插入到SQL服务器数据库的表中。从文本文件到SQL服务器(?速度法)

我在做什么是简单,就是(缩短了“......”为了简洁):

while ((line = file.ReadLine()) != null) 
{ 
    string[] split = line.Split(new Char[] { '|' }); 

    SqlCommand cmd = new SqlCommand("INSERT INTO NEW_AnnualData VALUES (@YR1984, @YR1985, ..., @YR2012)", myconn); 
    cmd.Parameters.AddWithValue("@YR1984", split[0]); 
    cmd.Parameters.AddWithValue("@YR1985", split[1]); 
    ... 
    cmd.Parameters.AddWithValue("@YR2012", split[28]); 

    cmd.ExecuteNonQuery(); 
} 

现在,这是工作,但一段时间服用。这是我第一次用大量的数据做任何事情,所以我需要确保:A)我以高效的方式做到这一点,B)我的期望不是太高。

使用SELECT COUNT(),而循环是怎么回事,我可以看数量上去了一段时间。所以我用了一个时钟和一些基本的数学来确定事物的运行速度。 在60秒内,有73881个插入。这是每秒1231个插入。问题是,这是一个平均速度,还是我表现不佳?如果是后者,我能做些什么来提高性能?

我看过一些关于SSIS是有效的用于这一目的完全吻合。但是,我需要通过单击Windows窗体中的按钮来执行此操作,而不是通过SISS。

回答

2

看一看SqlBulkCopy on MSDN,或nice blog post here。对我而言,每秒钟可达数万次插入。

+0

这正是我所需要的。起初我有一个问题,因为有太多的数据,我得到OutOfMemory异常,但这篇文章让我走上了正确的道路:http://stackoverflow.com/questions/9442171/a-way-out-from -getting-systemoutofmemoryexception-while-imports-from-large-tex – CptSupermrkt 2012-03-07 00:27:05

1

我认为SSIS是很多比这种类型的方法更快,但有一堆变量会影响性能。

如果你想与SSIS实验,使用导入和导出向导Management Studio中生成一个SSIS包将导入一个管道分隔的文件。您可以将该程序包存储并从.NET应用程序运行。

有关如何以编程方式运行SSIS包的信息,请参阅此文章:http://blogs.msdn.com/b/michen/archive/2007/03/22/running-ssis-package-programmatically.aspx。它包括如何从客户端,服务器或任何地方运行的选项。

而且,看看本文的其他方法可以改善一般批量插入性能。 http://msdn.microsoft.com/en-us/library/ms190421.aspx

+0

这不需要客户端部署SSIS组件吗?如果你升级你的SQL Server版本,SSIS包通常也需要更新。 – Andomar 2012-03-06 07:04:44

+0

上面的链接详细介绍了从代码执行SSIS包的多种方法,其中3个可以远程运行,包括选项,无需部署客户端工具。另外,我不需要对从05到08到R2的SSIS包进行任何更改。因人而异。 – 2012-03-06 07:13:40

2

我有Andomar同意。我真的很喜欢SqlBulkCopy。它非常快(您需要play around with BatchSizes以确保找到适合您的情况的文件)。

有关讨论各种选项的真正深入的文章,请查看Microsoft的“数据加载性能指南”; http://msdn.microsoft.com/en-us/library/dd425070(v=sql.100).aspx

另外,看看SqlBulkCopy为CSV Reader的C#示例。它不是免费的,但如果你能够在更短的时间内写出一个快速准确的解析器,那就去做吧。至少,它会给你一些想法。

2

哦 - 这种方法会给你带来惊人的表现。尝试使用BULK INSERT,如下:

BULK INSERT MyTable 
    FROM 'e:\orders\lineitem.tbl' 
    WITH 
    (
     FIELDTERMINATOR ='|', 
     ROWTERMINATOR ='\n' 
    ) 

这是在性能方面的最佳解决方案。有一个缺点,即文件必须存在于数据库服务器上。有两种解决这个,我已经在过去使用的,如果你不从那里你正在运行的进程访问服务器的文件系统。一种方法是在工作站上安装SQL Express实例,将主服务器添加为工作站实例的链接服务器,然后运行“BULK INSERT MyServer.MyDatabase.dbo.MyTable ...”。另一种选择是将CSV文件重新格式化为XML格式,该格式可以非常快速地处理,然后将XML传递给使用OPENXML进行查询和处理。 BULK INSERT和OPENXML在MSDN上都有很好的文档记录,您最好仔细阅读这些示例。

相关问题