您认为以下两个语句中哪一个对于删除大量行是最有效的?使用计数优化DELETE语句
声明#1:
DELETE TOP (@count) FROM ProductInfo WHERE productId = @productid
声明#2:派生表
DELETE t1 FROM (SELECT TOP (@count) * from ProductInfo
WHERE productId = @productId v) t1
您认为以下两个语句中哪一个对于删除大量行是最有效的?使用计数优化DELETE语句
声明#1:
DELETE TOP (@count) FROM ProductInfo WHERE productId = @productid
声明#2:派生表
DELETE t1 FROM (SELECT TOP (@count) * from ProductInfo
WHERE productId = @productId v) t1
两者既不。由于单个事务日志增长问题,您在处理大量数据时需要批量删除。假设你要删除所有记录,对于一个给定@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。
由于这两个查询执行完全相同的任务,我会使用第一个,因为它更简单阅读并理解。
(此外,由于这两个查询做同样的工作,我怀疑他们会产生相同的执行计划 - 你可以检查这个?)
1.如果delete语句失败会发生什么?它是否在while循环中继续? 2.如果删除失败,会发生什么情况,它是否设置了rowcount = 0并且真正退出循环? – RPS 2010-09-28 17:17:13
向每个示例帖子添加错误处理将会膨胀该示例并稀释该示例的值。但是,如果你明确要求错误处理,那么我建议将它包装在BEGIN TRY/BEGIN CATCH块中。然后,根据错误是什么进行适当的处理。 – 2010-09-28 17:31:11
一个@batchSize,除非它已通过各种方法明确禁用,否则它将导致锁定升级。 – etliens 2010-09-28 17:58:30