我在数据库中有表A,B和C.我必须将从A和B获得的结果放入表C中。
目前,我有一个SP,它将A和B的结果返回给C#应用程序。此结果将使用“System.Data.SqlClient.SqlBulkCopy”复制到表C中。 advanat是在使用批量复制的插入过程中,不会创建日志文件。
我希望通过处理SP本身的插入来避免这种额外的流量。但是,它不应该使用任何日志文件。有没有办法实现这个目标?
请分享您的想法。
数据量:150,000
数据库:SQL Server 2005
数据库处于完全恢复模式;它无法更改。 SELECT INTO 在这种情况下有用吗?
编辑:当我使用System.Data.SqlClient.SqlBulkCopy时,操作在3分钟内完成;正常插入需要30分钟...这个特殊的操作无需恢复;但是,必须恢复数据库中的其他操作 - 因此我无法更改整个数据库的恢复模式。
由于
Lijo
答案 0 :(得分:1)
您可以将SELECT INTO
与BULK_LOGGED
恢复模型一起使用,以便最小化写入事务日志的记录数,如INTO Clause documentation (MSDN)的示例B中所述:
ALTER DATABASE AdventureWorks2008R2 SET RECOVERY BULK_LOGGED;
GO
-- Put your SELECT INTO statement here
GO
ALTER DATABASE AdventureWorks2008R2 SET RECOVERY FULL;
批量插入也是必需的,如果您希望对事务日志的影响最小,如Optimizing Bulk Import Performance (MSDN)中所述:
对于完全恢复模式下的数据库,在批量导入期间执行的所有行插入操作都会在事务日志中完全记录。对于大型数据导入,这可能导致事务日志快速填写。对于批量导入操作,最小日志记录比完整日志记录更有效,并降低批量导入操作填充日志空间的可能性。 要在通常使用完整恢复模型的数据库上最低限度地记录批量导入操作,您可以先将数据库切换到批量记录恢复模型。批量导入数据后,切换恢复模型回到完全恢复模式。
(强调我的)
即。如果您在执行批量插入之前尚未将数据库恢复模型设置为BULK_LOGGED
,那么您将无法获得使用批量加密项的最小事务日志记录的好处,因此事务日志不会是您的减速源。 (SqlBulkCopy
类不会自动为您执行此操作或其他任何操作)
答案 1 :(得分:0)
也许你可以使用select into。 试着看看http://msdn.microsoft.com/en-us/library/ms191244.aspx
答案 2 :(得分:0)
在SQL Server 2008中,在继续进行最少日志记录的操作之前,无需将数据返回到客户端/应用程序。您可以在查询之后立即在存储过程中执行此操作,从而生成要插入表C的结果。
请参阅Insert:具体说明“使用INSERT INTO ... SELECT以最小记录批量加载数据”
[编辑]:从那时起,您的问题已经扩展到包含您正在使用FULL恢复模式,因此您无法从最少的日志记录操作中受益。
相反,您应该集中精力优化数据插入过程,而不是考虑自己的日志记录开销。
答案 3 :(得分:0)
您能举例说明您的程序处理吗?
通常情况下,我认为基于集合的150,000行插入(没有链接的服务器或任何东西)几乎不需要大多数安装。
使用查询选择150,000行需要多长时间?
您使用的是游标和循环而不是单个INSERT INTO C SELECT * FROM (some combination of A and B)
吗?
是否存在导致操作等待其他操作完成的阻塞?
如果您的数据库处于完全恢复模式,它将记录操作 - 这就是使用数据库的方式。数据库已被告知使用该模型,它将这样做以确保它符合要求。
想象一下,如果你告诉数据库一个列需要是唯一的,但它实际上并没有为你强制执行它!对于从规范文档中删除的便利贴的评论,它的价值还不够!
答案 4 :(得分:0)
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.
希望这会对你有所帮助。