删除sql server中的大量数据

mas*_*ani 8 sql-server performance sql-delete

假设我有一张10000000记录的表.这两种解决方案有什么区别?

  1. 删除数据如:

    DELETE FROM MyTable
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用应用程序逐行删除所有数据:

    DELETE FROM MyTable WHERE ID = @SelectedID
    
    Run Code Online (Sandbox Code Playgroud)

第一种解决方案是否具有最佳性能?对日志和性能有什么影响?

Ada*_*Dev 21

如果您需要限制需要删除的行而不进行完全删除,或者您不能使用TRUNCATE TABLE(例如,表由FK约束引用,或包含在索引视图中),那么您可以执行删除块:

DECLARE @RowsDeleted INTEGER
SET @RowsDeleted = 1

WHILE (@RowsDeleted > 0)
    BEGIN
        -- delete 10,000 rows a time
        DELETE TOP (10000) FROM MyTable [WHERE .....] -- WHERE is optional
        SET @RowsDeleted = @@ROWCOUNT
    END
Run Code Online (Sandbox Code Playgroud)

一般来说,TRUNCATE是最好的方法,如果可能的话,我会使用它.但它不能在所有场景中使用.另请注意,TRUNCATE将重置表的IDENTITY值(如果有).

如果您使用的是SQL 2000或更早版本,则TOP条件不可用,因此您可以使用SET ROWCOUNT.

DECLARE @RowsDeleted INTEGER
SET @RowsDeleted = 1
SET ROWCOUNT 10000 -- delete 10,000 rows a time

WHILE (@RowsDeleted > 0)
    BEGIN
        DELETE FROM MyTable [WHERE .....] -- WHERE is optional
        SET @RowsDeleted = @@ROWCOUNT
    END
Run Code Online (Sandbox Code Playgroud)

  • 你可能想要使用SET ROWCOUNT来支持SELECT/INSERT/UPDATE/DELETE TOP(N)......原因是什么?看看这里:http://msdn.microsoft.com/en-us/library/ms143729.aspx和这里:https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?反馈ID = 282528 (2认同)

Nil*_*idt 14

如果您的表中有很多记录并且想要全部删除它们,则应考虑使用truncate <table>而不是delete from <table>.它会快得多,但要注意它不能激活触发器.

有关更多详细信息,请参阅(本例为sql server 2000):http: //msdn.microsoft.com/en-us/library/aa260621%28SQL.80%29.aspx

逐行删除应用程序中的表将在很长一段时间内结束,因为您的dbms无法优化任何事情,因为它事先不知道,您将删除所有内容.

  • 如果您仍处于执行它的事务范围内,则可以回滚截断,这与普遍认为它是事务化的相反 - 在提交之前不会删除已释放的IAM,因此可以通过恢复IAM来回滚它. (4认同)