SQL Server 2008上的大容量删除(是否有类似于大容量复制(bcp)的删除数据功能?)
SQL Server中是否有大容量删除的解决方案 我不能使用TRUNCATE,因为我想使用WHERE限制操作中的行 是否有类似于批量复制(bcp)的方法来删除数据?否 您需要一个带有WHERE子句的DELETE:这是标准SQL 您可以执行以下批量删除操作:SQL Server 2008上的大容量删除(是否有类似于大容量复制(bcp)的删除数据功能?),sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,SQL Server中是否有大容量删除的解决方案 我不能使用TRUNCATE,因为我想使用WHERE限制操作中的行 是否有类似于批量复制(bcp)的方法来删除数据?否 您需要一个带有WHERE子句的DELETE:这是标准SQL 您可以执行以下批量删除操作: SELECT 'Starting' --sets @@ROWCOUNT WHILE @@ROWCOUNT <> 0 DELETE TOP (xxx) MyTable WHERE ... 如果您想删除表的一部分,而不是截断
SELECT 'Starting' --sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
DELETE TOP (xxx) MyTable WHERE ...
如果您想删除表的一部分,而不是
截断它,可以做几件事
您可以选择表格的一部分到一个新表格中,然后切换这两个表格,如下所示:
SELECT *
INTO tmp_MyTable
FROM MyTable
WHERE Key='Value'
IF @@ROWCOUNT > 0
BEGIN
EXEC sp_rename MyTable, old_MyTable, NULL
EXEC sp_rename tmp_MyTable, MyTable, NULL
TRUNCATE old_MyTable
END
其次,如果使用分区,可以在同一分区方案上创建相同的(空)表。。如果根据存档/清除逻辑对表进行分区,则可以将一个分区块从主表移动到新表,然后截断新表。。例如:
ALTER TABLE MyTable
SWITCH PARTITION 15 TO purge_MyTable PARTITION 2
GO;
TRUNCATE TABLE purge_MyTable
附言。
分区在SQL 2005/08 Ent中可用
希望这有帮助 Sychare Jedko
TRUNCATE的优点是避免在日志文件中记录每次删除。TRUNCATE语句将为整个批处理创建一个条目(在日志中) 在处理暂存表时遇到了类似的问题,该表在使用适当的锁进行扩展时遇到了问题
由于我们只在一个位置引用了相关的表,因此我们只是将该引用替换为对动态表名的查询,该查询是使用类似于gbn建议的“select into”创建的
这是可以维护的,因为暂存表在代码中只在一个位置被引用,并且额外的数据库调用和表创建的费用在仓库上下文中是合理的。如果您只有几百条记录或在代码中多次引用该表,那么这种方法可能不起作用。在处理数百万行时,我更喜欢使用WHERE语句并在复制表中使用SELECT,删除原始表并重命名副本(返回原始名称)
不过,您应该记住(FK)键、约束等内容。但是使用这种方法可以避免日志的badazz大小,并且可以避免在块中删除的巨大时间消耗
/Snedker检查一下这个
来自MSDN的文章
关于
及
您可以使用循环按块删除:
我的解决方案是每次删除100条记录:
DECLARE @Rows INT
SET @Rows = 1
WHILE (@Rows > 0)
BEGIN
with ToDelete(EMailNotificationID)
as
(
select top 100 q.EMailNotificationID from email
)
delete from ToDelete
SET @Rows = @@ROWCOUNT
END
如果事务量很大,则取决于备份模式和日志大小,做更多的日志备份来释放日志中的空间…在临时表中保存数据会让你付出更多的内存使用。@Allan Chua:你能证明临时表只保存在内存中吗?哎哟…学会了艰难的方法…在我可以应用这种方法的情况下批量删除2小时你还应该确保恢复模型是批量记录的
或SIMPLE
并使用和TABLOCK
锁定表以进行第二次插入,否则事务日志仍然会很大。看看好答案。仅供参考,您也可以使用ALTER TABLE..SWITCH而不进行分区,但是您需要两个离散的表。+1使用临时表可能在删除大量行时获得最快的结果。如果目标是回收空间,我还将在操作结束时为所有db文件运行DBCC SHRINKFILE
。
DECLARE @Rows INT
SET @Rows = 1
WHILE (@Rows > 0)
BEGIN
with ToDelete(EMailNotificationID)
as
(
select top 100 q.EMailNotificationID from email
)
delete from ToDelete
SET @Rows = @@ROWCOUNT
END