【问题标题】:What's the best way to use SqlBulkCopy to fill a really large table?使用 SqlBulkCopy 填充非常大的表的最佳方法是什么?
【发布时间】:2008-10-13 00:45:15
【问题描述】:

每晚,我需要使用超过 800 万条记录从 ODBC 源填充 SQL Server 2005 表。目前我正在使用来自链接服务器的插入语句,其语法选择类似于:

Insert Into SQLStagingTable from Select * from OpenQuery(ODBCSource, 'Select * from SourceTable')

这确实效率低下,需要数小时才能运行。我正在使用类似于this question 中的代码的 SqlBulkInsert 代码编写解决方案。

该问题中的代码首先在内存中填充数据表,然后将该数据表传递给 SqlBulkInserts WriteToServer 方法。

如果填充的数据表使用的内存比它正在运行的机器上的可用内存多(在我的例子中是 16GB 内存的服务器),我该怎么办?

我考虑过使用重载的 ODBCDataAdapter fill 方法,它只允许您填充从 x 到 n 的记录(其中 x 是起始索引,n 是要填充的记录数)。然而,这可能是一个比我目前拥有的更慢的解决方案,因为这意味着在源上多次重新运行 select 语句。

我该怎么办?只需一次填充整个内容并让操作系统管理内存?我应该分块填充它吗?还有其他我没有想到的解决方案吗?

【问题讨论】:

    标签: c# .net sql-server vb.net sqlbulkcopy


    【解决方案1】:

    最简单的方法是对您的 odbc 数据源使用 ExecuteReader() 并将 IDataReader 传递给 WriteToServer(IDataReader) 重载。

    大多数数据读取器实现只会将总结果的一小部分保留在内存中。

    【讨论】:

      【解决方案2】:

      SSIS 表现良好并且非常易于调整。以我的经验,800 万行并没有超出它的范围。我的一个较大的 ETL 每天提取 2400 万行,并进行主要的转换和维度数据仓库操作。

      【讨论】:

      • 我真的需要花时间学习 SSIS。我听说了它的好消息,但它肯定比 DTS 有更多的学习曲线。
      • 是的,学习曲线要​​陡峭得多,但是,在几周内它真的可以让你得到回报。
      【解决方案3】:

      如果您在目标表上有索引,您可能会考虑禁用这些索引,直到插入记录?

      【讨论】:

      • 在这种情况下,我正在填充一个新创建的临时表,然后在创建临时表后更新活动表,然后删除临时表。所以我在临时表上没有任何索引。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 2012-08-30
      • 2010-11-26
      • 1970-01-01
      • 2019-01-30
      • 2021-05-20
      • 1970-01-01
      相关资源
      最近更新 更多