将数百万条记录从平面文件插入 SQL Server 的陷阱是啥?
Posted
技术标签:
【中文标题】将数百万条记录从平面文件插入 SQL Server 的陷阱是啥?【英文标题】:What are the pitfalls of inserting millions of records into SQL Server from flat file?将数百万条记录从平面文件插入 SQL Server 的陷阱是什么? 【发布时间】:2010-09-13 13:59:03 【问题描述】:我即将开始编写一个 Windows 窗体应用程序,该应用程序将打开一个 txt 文件,该文件以管道分隔,大小约为 230 mb。然后,此应用程序会将这些数据插入到 sql server 2005 数据库中(显然这需要迅速发生)。我在这个项目中使用 c# 3.0 和 .net 3.5。
我不是要应用程序,只是在这里提供一些公共建议和潜在陷阱建议。从我收集到的网站上,SQL 批量复制是先决条件,有什么我应该考虑的(我认为仅使用表单应用程序打开 txt 文件将是一项巨大的努力;也许将其分解为 blob 数据?)。
谢谢,如果有人需要,我会编辑问题以便清楚。
【问题讨论】:
【参考方案1】:您必须编写一个 winforms 应用程序吗?使用 SSIS 可能更容易和更快。有一些内置任务可用,尤其是Bulk Insert task。
另外,值得检查Flat File Bulk Import methods speed comparison in SQL Server 2005.
更新:如果您是 SSIS 的新手,请查看其中一些网站,让您快速上手。 1)SSIS Control Flow Basics 2)Getting Started with SQL Server Integration Services
这是另一个方法:importing Excel file into SQL 2005。
【讨论】:
在 SSIS 中更容易、更快...同意。 我发现 SSIS 对 keester 来说是一个巨大的痛苦。它更频繁地出现奇怪的原因,并且需要 DBA 访问数据库服务器以进行故障排除/修复/重新运行(这在我们的生产环境中受到限制)。 我同意这需要一点点掌握,尤其是在故障排除和部署方面。 我真的很喜欢 Gulzar 的这个想法,你有任何额外的超级链接可以帮助这个项目吗?你提供的两个太棒了。 @Ron:我同意 100% 在使用过 DTS 并彻底了解它之后,我无法忍受 SSIS 并放弃了它以进行与此问题相同的大型项目.. 插入数百万行来自平面文件,我无法控制我无法纠正的异常的创建。 SSIS 失败了。【参考方案2】:这将是一项流媒体工作。
如果可以,请不要在此处使用事务。交易成本太高了。
因此,您要做的是一次读取文件一行,然后一次将其插入一行。您应该将失败的插入转储到另一个文件中,以便稍后诊断并查看失败的位置。
起初我会继续尝试批量插入几百行,只是为了查看流是否正常工作,然后你可以打开所有你想要的。
【讨论】:
【参考方案3】:您可以尝试使用SqlBulkCopy。它可以让您从“任何数据源”中提取数据。
【讨论】:
【参考方案4】:顺便说一句,有时删除表的索引并在批量插入操作后重新创建它们会更快。
【讨论】:
【参考方案5】:您可以考虑从完全恢复切换到批量记录。这将有助于使您的备份保持合理的大小。
【讨论】:
我认为批量记录模式会使您的日志更小,但会使日志备份更大。 msdn 不是说 (msdn.microsoft.com/en-us/library/ms175987.aspx) 吗? 不,它提醒您,批量日志恢复与完全恢复并没有太大区别,some operations 除外;如果您不使用这些操作,则基本上是在进行完全恢复。在这种情况下,OP 可以使用大容量日志恢复执行BULK INSERT
,以避免记录这些插入(知道插入可以在必要时重复)。【参考方案6】:
我完全推荐 SSIS,您可以在相对较短的时间内读取数百万条记录并一路清理它们。
您需要留出一些时间来掌握 SSIS,但这应该会有所收获。 SO上还有一些其他线程可能有用:
What's the fastest way to bulk insert a lot of data in SQL Server (C# client)
What are the recommended learning material for SSIS?
您还可以从 C# 创建包。我有一个 C# 程序,它从遗留系统读取 3GL“主文件”(使用我为相关项目提供的 API 解析为对象模型),获取包模板并对其进行修改以生成用于 ETL 的包。
【讨论】:
【参考方案7】:您所说的数据量实际上并没有那么大。我不知道你的效率问题是什么,但如果你可以等待几个小时让它插入,你可能会惊讶于用一种非常幼稚的技术来完成这将是多么容易,一次只插入每一行.一次将 1000 行左右的行组合在一起并将它们提交到 SQL Server 也可能会加快速度。
如果您不需要尽可能快的速度,这只是一个可以为您节省大量编程时间的建议。根据此导入运行的频率,节省几天的编程时间可能很值得,以换取在运行时等待几个小时。
【讨论】:
【参考方案8】:您可以使用 SSIS 进行读取和插入,但可以从您的 WinForms 应用程序中将其作为一个包调用。然后您可以将源、目标、连接字符串等内容作为参数/配置传递。
操作方法:http://msdn.microsoft.com/en-us/library/aa337077.aspx
您可以在 SSIS 中设置转换和错误处理,甚至可以根据输入参数创建逻辑分支。
【讨论】:
【参考方案9】:如果文件的列格式与数据需要结束的目标表匹配,我更喜欢使用命令行实用程序bcp来加载数据文件。它速度极快,您可以为任何无法插入的“奇数”记录指定错误文件。
如果您需要为其存储命令行参数(服务器、数据库、用户名/密码或受信任的连接、表、错误文件等),您的应用可以启动该命令。
与运行 BULK INSERT SQL 命令相比,我更喜欢这种方法,因为数据文件不需要位于数据库服务器可访问的系统上。要使用批量插入,您必须指定要加载的数据文件的路径,因此它必须是运行加载的数据库服务器上的系统用户可见和可读的路径。通常对我来说太麻烦了。 :-)
【讨论】:
以上是关于将数百万条记录从平面文件插入 SQL Server 的陷阱是啥?的主要内容,如果未能解决你的问题,请参考以下文章
将数百批 500k - 300 万条记录插入 PostgreSQL 数据库的最快方法
如何使用 insert 语句将数百万不同 RDBMS 的数据插入 SQL Server 数据库?