将大规模CSV文件上载到SQL Server数据库

我需要将大量(16GB,6500万条记录)CSV文件上传到SQL Server 2005数据库中的单个表。 有没有人对最佳方法有任何指示?

细节

我目前正在使用C#控制台应用程序(.NET framework 2.0)将导入文件拆分为50000条记录的文件,然后处理每个文件。 我使用SqlBulkCopy类将数据从控制台应用程序上传到数据库中,批量为5000.分割文件大约需要30分钟,上传整个数据集(6500万条记录)大约需要4.5小时。 生成的文件大小和批量上载大小都是配置​​设置,我正在研究增加两者的值以提高性能。 要运行该应用程序,我们使用具有16GB RAM的四核服务器。 该服务器也是数据库服务器。

更新

鉴于到目前为止的答案,请注意在导入之前:

  • 截断数据库表,并删除所有索引和约束。
  • 数据库收缩,回收磁盘空间。

导入完成后:

  • 索引将重新创建

如果您可以建议任何不同的方法,或者我们可以改进现有导入应用程序的方法,我将不胜感激。 谢谢。

相关问题

以下问题可能对处理此问题的其他人有用:

  • 从平面文件向SQL Server 2005插入数百万条记录的潜在缺陷

我已经研究了改变批量大小和拆分文件大小的影响,发现批量500条记录和200,000条记录的拆分文件最适合我的应用程序。 使用SqlBulkCopyOptions.TableLock也有帮助。 有关详细信息,请参阅此问题的答案。

我还研究了使用SSIS DTS包和BULK INSERT SQL脚本。 SSIS包看起来更快,但没有让我能够记录无效记录等BULK INSERT SQL脚本虽然比SSIS包慢,但比C#应用程序要快得多。 它确实允许我记录错误等,因此,我接受来自ConcernedOfTunbridgeWells的BULK INSERT答案作为解决方案。 我知道这可能不是面对这个问题的每个人的最佳答案,但它解决了我的直接问题。

感谢所有回复的人。

此致,MagicAndi

BULK INSERT从DBMS本身运行,从服务器上的目录中读取bcp控制文件描述的文件(或安装在其上)。 编写一个将文件拆分为较小块的应用程序,将它们放在适当的目录中,执行一个执行一系列BULK INSERTS的包装器。 如有必要,您可以并行运行多个线程。

这可能与批量负载一样快。 此外,如果批量装入文件中有合适的分区键,请将登台表放在分区方案上。

此外,如果要批量加载到具有聚簇索引的表中,请确保数据的排序顺序与索引相同。 合并排序是您的大数据集的朋友。

您是否尝试过SSIS(SQL Server Integration Services)。

您已经使用的SqlBulkCopy类将是您最好的选择。 您可以在c#代码中从这里做的最好的事情是试验您的特定系统和数据,以了解哪种批处理尺寸最佳。 但你已经这样做了。

除了客户端代码之外,您可以使用服务器执行某些操作以使导入更有效:

  • 尝试在开始导入之前设置表和数据库大小,使其大到足以容纳整个集合。 你不想在这个过程中依赖自动增长。

  • 根据数据的排序方式和表中的任何索引,您可以更好地删除与导入记录的顺序不匹配的任何索引,然后在导入后重新创建它们。

  • 最后,尝试并行运行它是很诱人的,一些线程一次进行批量插入。 但是,最大的瓶颈几乎可以肯定是磁盘性能。 你可以对物理服务器做些什么来改进它(新磁盘,san等)将会有更多帮助。

您可以按如下方式保存拆分文件的步骤:

  • 实例化IDataReader以从输入CSV文件中读取值。 有几种方法可以做到这一点:最简单的方法是使用Microsoft OleDb Jet驱动程序。 谷歌如果您需要更多信息 – 例如, 这个StackOverflow问题中有一些信息。

    另一种方法是使用www.csvreader.com使用的技术。

  • 实例化SqlBulkCopy对象,将BatchSize和BulkCopyTimeout属性设置为适当的值。

  • 将IDataReader传递给SqlBulkCopy.WriteToServer方法。

我已成功使用此技术处理大文件,但不如您的大。

请参阅此博客文章以进行比较。 似乎最好的替代方法是使用BulkInsert并将TABLOCK选项设置为true。

您是否尝试在Sql Server中使用批量插入方法 ?

最近,我不得不上传/导入很多东西(构建一个PHP脚本)。

我决定将它们记录下来进行记录。

当然,它需要更长的时间,但对我来说,以下几点很重要: – 轻松暂停过程 – 更好的调试

这只是一个提示。

问候,Benedikt

BULK INSERT可能已经是最快的方式了。 通过在稍后插入和重新建立索引和约束时删除索引和约束,可以获得额外的性能。 最高性能影响来自聚簇索引。

您是否尝试过SQL Server Integration Services? 它可能能够更好地处理如此大的文本文件

只是要检查一下,如果你插入的表上没有索引,你的插入会更快。

我的场景是这样的:在SQL服务器上创建SSIS包,使用BLUK插入到sql中,在DataBase中创建存储过程,从T-SQL代码运行该包

之后使用FTP将文件发送到SQL服务器并调用SSIS包usinfg存储过程