2010-09-28 63 views
2

您认为以下两个语句中哪一个对于删除大量行是最有效的?使用计数优化DELETE语句

声明#1:

DELETE TOP (@count) FROM ProductInfo WHERE productId = @productid 

声明#2:派生表

DELETE t1 FROM (SELECT TOP (@count) * from ProductInfo 
       WHERE productId = @productId v) t1 

回答

6

两者既不。由于单个事务日志增长问题,您在处理大量数据时需要批量删除。假设你要删除所有记录,对于一个给定@ProductID:

declare @batchSize int = 10000; 
do while(1=1) 
begin 
    delete top(@batchSize) from ProductInfo where productId = @productId; 
    if (0 = @@rowcount) 
     break; 
end 

两种形式删除您发布的基本一致,最重要的是该表是由基于productId键集群的关键组织。如果这不是真的,并且您有productId的NC指数,则必须校准@batchSize以避免index tipping point

+0

1.如果delete语句失败会发生什么?它是否在while循环中继续? 2.如果删除失败,会发生什么情况,它是否设置了rowcount = 0并且真正退出循环? – RPS 2010-09-28 17:17:13

+0

向每个示例帖子添加错误处理将会膨胀该示例并稀释该示例的值。但是,如果你明确要求错误处理,那么我建议将它包装在BEGIN TRY/BEGIN CATCH块中。然后,根据错误是什么进行适当的处​​理。 – 2010-09-28 17:31:11

+0

一个@batchSize,除非它已通过各种方法明确禁用,否则它将导致锁定升级。 – etliens 2010-09-28 17:58:30

2

由于这两个查询执行完全相同的任务,我会使用第一个,因为它更简单阅读并理解。

(此外,由于这两个查询做同样的工作,我怀疑他们会产生相同的执行计划 - 你可以检查这个?)