SQL DELETE - 最大行数

时间:2011-12-29 20:56:45

标签: sql sql-server max sql-delete

对SQL语句中要删除的行数应该有什么限制?

我们需要删除1到数十万行,并且需要应用某种最佳实践限制,以便在每次清空废纸篓时都不会完全杀死SQL服务器或填满日志。

此问题并非特定于任何类型的数据库。

6 个答案:

答案 0 :(得分:12)

这是一个非常广泛的问题,基本上归结为“它取决于”。影响它的因素包括:

  • 您的并发级别是多少? delete语句对受影响的行放置独占锁。取决于数据库引擎,已删除的数据分布等,可能会升级到页面或整个表格。您的数据阅读器是否可以在删除期间被阻止?

  • 删除声明有多复杂?您加入了多少个其他表,或者是否有复杂的WHERE子句?有时,删除行的标识可能比删除本身更“昂贵”,因此一次大删除可能会“更便宜”。

  • 您是否担心死锁?当您减小删除的大小时,您的死锁“足迹”会减少。理想情况下,单行删除将始终成功。

  • 您是否关心吞吐量性能?与任何SQL语句一样,通常有一定量的开销(连接内容,查询解析,返回结果等)。从单连接的角度来看,1000行删除将比1000 x 1行删除更快。

  • 不要忘记索引维护开销,碎片清理或任何触发器。它们也会影响您的系统。

但总的来说,我的每个语句的基线为1000行。我使用过的大多数系统(子“企业”)最终都有每个删除500到5000个记录的甜点。我喜欢这样做:

set rowcount 500

select 1    -- Just to force @@rowcount > 0
while @@ROWCOUNT > 0
delete from [table]
     [where ...]

答案 1 :(得分:4)

虽然使用set rowcount选项限制删除影响的行数然后执行循环是非常好的(我之前已经使用过很多次),请注意从SQL 2012开始,这不会是一个选项(见BOL)。

因此,另一个选项可能是使用TOP子句限制要删除的行数。即。

SELECT 1

WHILE @@ROWCOUNT > 0
BEGIN
    DELETE TOP (#)
    FROM mytable
    [WHERE ...]
END

答案 2 :(得分:1)

除非你有很多要验证的触发器或完整性限制,否则删除操作不应该那么昂贵。

但是,如果您关注性能,我最初的预感是将相应的行标记为已删除,然后在定期清理期间将其物理删除。但我不是这个的忠实粉丝,因为你必须更改该表上的任何查询以排除逻辑但不是物理删除的行。

答案 3 :(得分:1)

每当我看到一个常规删除大量行的数据库时,我就会认为数据模型或处理设计不是最佳的。为什么要加载100万行然后删除它们?如果您需要执行清除历史数据等操作,请考虑表分区。

答案 4 :(得分:0)

一般的答案是删除表并重新创建它,这是一个表现良好的解决方案,但适用于完整的表

答案 5 :(得分:0)

我遇到了这个问题,发现自己的答案非常有效:进行子选择。

从网址所在的网址中删除(从网址中选择前10000个网址)