SQL Server 2008上的大容量删除(是否有类似于大容量复制(bcp)的删除数据功能?)

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 ... 如果您想删除表的一部分,而不是截断

SQL Server中是否有大容量删除的解决方案

我不能使用TRUNCATE,因为我想使用WHERE限制操作中的行

是否有类似于批量复制(bcp)的方法来删除数据?

您需要一个带有WHERE子句的DELETE:这是标准SQL

您可以执行以下批量删除操作:

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