我需要将大量(16GB,6500万条记录)CSV文件上传到SQL Server 2005数据库中的单个表。有没有人对最佳方法有任何指示?
详情
我目前正在使用C#控制台应用程序(.NET framework 2.0)将导入文件拆分为50000条记录的文件,然后处理每个文件。我使用SqlBulkCopy类将数据从控制台应用程序上传到数据库中,批量为5000.分割文件大约需要30分钟,上传整个数据集(6500万条记录)大约需要4.5小时。生成的文件大小和批量上载大小都是配置设置,我正在研究增加两者的值以提高性能。要运行该应用程序,我们使用具有16GB RAM的四核服务器。该服务器也是数据库服务器。
更新
鉴于目前为止的答案,请注意在导入之前:
导入完成后:
如果您可以建议任何不同的方法,或者我们可以改进现有导入应用程序的方法,我将不胜感激。感谢。
相关问题
以下问题可能对处理此问题的其他人有用:
解决方案
我已经研究了改变批量大小和拆分文件大小的影响,发现批量500条记录和200,000条记录的拆分文件最适合我的应用程序。使用SqlBulkCopyOptions.TableLock
也有帮助。有关详细信息,请参阅此question的答案。
我还研究了使用SSIS DTS包和BULK INSERT
SQL脚本。 SSIS包看起来更快,但没有让我能够记录无效记录等。BULK INSERT
SQL脚本虽然比SSIS包慢,但比C#应用程序要快得多。它确实允许我记录错误等,因此,我接受来自ConcernedOfTunbridgeWells的BULK INSERT
答案作为解决方案。我知道这对于遇到这个问题的每个人来说可能不是最好的答案,但它解决了我当前的问题。
感谢所有回复的人。
此致,MagicAndi
答案 0 :(得分:5)
BULK INSERT
从DBMS本身运行,从服务器上的目录中读取bcp控制文件描述的文件(或安装在其上)。编写一个将文件拆分为较小块的应用程序,将它们放在适当的目录中,执行一个执行一系列BULK INSERTS
的包装器。如有必要,您可以并行运行多个线程。
这可能与批量负载一样快。此外,如果批量加载文件中有合适的分区键,请将分段表放在分区方案上。
此外,如果要批量加载到具有聚簇索引的表中,请确保数据的排序顺序与索引相同。合并排序是大数据集的朋友。
答案 1 :(得分:3)
您是否尝试过SSIS(SQL Server Integration Services)。
答案 2 :(得分:2)
您已经使用的SqlBulkCopy课程将是您最好的选择。从c#代码中可以做到的最好的方法就是试验您的特定系统和数据,以了解哪种批量大小最佳。但你已经这样做了。
除了客户端代码之外,您可以使用服务器执行某些操作以使导入更有效:
尝试在开始导入之前设置表和数据库大小,使其足够大以容纳整个集合。你不想在这个过程中依赖自动增长。
根据数据的排序方式和表中的任何索引,您可以更好地删除与导入记录的顺序不匹配的任何索引,然后在以后重新创建它们导入。
最后,尝试并行运行它很诱人,一些线程一次进行批量插入。但是,最大的瓶颈几乎可以肯定是磁盘性能。您可以对物理服务器进行任何改进(新磁盘,san等)的任何操作都会有所帮助。
答案 3 :(得分:2)
您可以按如下方式保存拆分文件的步骤:
实例化IDataReader以读取输入CSV文件中的值。有几种方法可以做到这一点:最简单的方法是使用Microsoft OleDb Jet驱动程序。如果您需要更多信息,可以使用谷歌 - 例如this StackOverflow question中有一些信息。
另一种方法是使用www.csvreader.com使用的技术。
实例化SqlBulkCopy对象,将BatchSize和BulkCopyTimeout属性设置为适当的值。
将IDataReader传递给SqlBulkCopy.WriteToServer方法。
我已成功使用此技术处理大型文件,但不如您的大。
答案 4 :(得分:1)
答案 5 :(得分:0)
您是否尝试在Sql Server中使用Bulk Insert method?
答案 6 :(得分:0)
最近,我不得不上传/导入很多东西(构建一个PHP脚本)。
我决定将它们记录下来进行记录。
当然,这需要更长的时间,但对我来说,以下几点非常重要: - 轻松暂停该过程 - 更好的调试
这只是一个提示。
的问候, 本尼迪克特
答案 7 :(得分:0)
BULK INSERT
可能已经是最快的方式了。通过在稍后插入和重新建立索引和约束时删除索引和约束,可以获得额外的性能。最高性能影响来自聚簇索引。
答案 8 :(得分:0)
您是否尝试过SQL Server Integration Services?它可能能够更好地处理如此大的文本文件
答案 9 :(得分:0)
只是要检查一下,如果你插入的桌子上没有索引,你的插入会更快。
答案 10 :(得分:0)
我这样做的场景是: 在SQL服务器上创建SSIS包,使用BLUK插入到sql中, 在DataBase中创建存储过程以从T-SQL代码
运行该包之后使用FTP将bluk insert的文件发送到SQL Server并调用SSIS Package usinfg存储过程