存储过程中的BulkCopy

我在数据库中有表A,B和C. 我必须将从A和B获得的结果放入表C中。

目前,我有一个SP,它将A和B的结果返回给C#应用程序。 使用“System.Data.SqlClient.SqlBulkCopy”将此结果复制到表C中。 advanat是在使用bulkcopy插入期间,不会创建日志文件。

我希望通过处理SP本身的插入来避免这种额外的流量。 但是,它不应该使用任何日志文件。 有没有办法实现这个目标?

请分享你的想法。

数据量 :150,000

数据库 :SQL Server 2005

数据库处于完全恢复模式; 它无法更改.. SELECT INTO在这种情况下有用吗?

编辑:当我使用System.Data.SqlClient.SqlBulkCopy时,操作在3分钟内完成; 在正常插入中需要30分钟……这个特殊操作无需恢复; 但是必须恢复数据库中的其他操作 – 因此我无法更改整个数据库的恢复模式。

谢谢

Lijo

您可以将SELECT INTOBULK_LOGGED恢复模型一起使用,以便最小化写入事务日志的记录数,如INTO条款文档(MSDN)的示例B中所述:

 ALTER DATABASE AdventureWorks2008R2 SET RECOVERY BULK_LOGGED; GO -- Put your SELECT INTO statement here GO ALTER DATABASE AdventureWorks2008R2 SET RECOVERY FULL; 

如果您希望对事务日志的影响最小,那么批量插入也是必需的,如优化批量导入性能(MSDN)中所述 :

对于完全恢复模型下的数据库,在批量导入期间执行的所有行插入操作都将完全记录在事务日志中。 对于大数据导入,这可能导致事务日志快速填充。 对于批量导入操作,最小日志记录比完全日志记录更有效,并降低批量导入操作填充日志空间的可能性。 要在通常使用完全恢复模型的数据库上最小化地记录批量导入操作,您可以先将数据库切换到批量记录的恢复模型。 批量导入数据后,将恢复模型切换回完全恢复模型。

(强调我的)

即如果您在执行批量插入之前尚未将数据库恢复模型设置为BULK_LOGGED ,那么您目前无法获得使用批量加密的最小事务日志记录的好处,因此事务日志不会成为您的减速源的来源。 ( SqlBulkCopy类不会自动为您执行此操作或任何操作)

也许你可以使用select into。 试着看看http://msdn.microsoft.com/en-us/library/ms191244.aspx

你能举例说明你的程序处理吗?

通常情况下,我认为在大多数安装中,基于集合的150,000行(没有链接服务器或任何东西)的插入几乎不需要时间。

用查询选择150,000行需要多长时间?

您是否使用游标和循环而不是单个INSERT INTO C SELECT * FROM (some combination of A and B)

是否存在导致操作等待其他操作完成的阻塞?

如果您的数据库处于完全恢复模式,它将记录操作 – 这就是使用数据库的方式。 数据库已被告知使用该模型,它将这样做以确保它符合要求。

想象一下,如果你告诉数据库一个列需要是唯一的,但实际上并没有为你强制执行它! 对于从规范文档中删除的便利贴的评论值得少!

在SQL Server 2008中,您无需在继续进行最少日志记录操作之前将数据返回到客户端/应用程序。 您可以在查询之后立即在存储过程中执行此操作,从而生成要插入表C的结果。

请参阅插入 :专门“使用INSERT INTO … SELECT以批量加载数据并使用最少日志记录”

[编辑]:从那时起,您的问题已经扩展到包括您正在使用FULL恢复模型,因此您无法从最少的日志记录操作中受益。

相反,您应该集中精力优化数据插入过程,而不是考虑自己的日志记录开销。

Insert data into table C in parts using insert into c select * from AandB WHERE ID < SOMETHING. Or you can take send output of a and b data as xml to stored procedure to insert bulk data. 希望这会帮助你。