高效删除顶部?

时间:2014-02-06 17:11:00

标签: sql-server performance

以1000或10000为单位从数据库中删除行是否更有效并最终更快?我不得不从许多表中删除大约300万行。我首先在100K行的块中删除了,但性能看起来并不好。我改为10000,似乎更快。想知道每个DELETE语句是否更小,如1K甚至更好。

思想?

我这样删除:

DELETE TOP(10000)
FROM TABLE
WHERE Date < '1/1/2012'

3 个答案:

答案 0 :(得分:1)

是,不,这取决于因锁定而导致的表用法。我会尝试以较慢的速度删除记录。所以与op的问题相反。

set rowcount 10000
while @@rowcount > 0
begin
    waitfor delay '0:0:1'      
    delete 
    from table 
    where date < convert(datetime, '20120101', 112)
end
set rowcount 0

答案 1 :(得分:1)

是的,确实如此。这一切都取决于你的服务器。我的意思是,上次我这样做的时候,我正在使用这个方法以6400万的增量删除东西(在那个时刻有大约140亿行,其中80%最终被删除的表)。我每隔10秒就删除一次。

这取决于你的硬件。更多粒度是更多的工作,但它意味着更少等待tx日志用于桌面上运行的其他事情。您必须尝试并找到您感到舒适的地方 - 没有最终的答案,因为它完全取决于桌子和硬件的使用。

答案 2 :(得分:1)

我们使用表分区在不到一秒的时间内删除了500万行,但这只来自一个表。它需要预先做好一些工作,但最终还是最好的方法。这对您来说可能不是最佳方式。

从我们关于分区的文档:

假设您要向表中添加500万行,但不希望在执行此操作时锁定表。我在订购系统中遇到了一个案例,我无法在不停止接受订单的情况下插入行。坏!如果要添加不与当前数据重叠的行,则分区是执行此操作的一种方法。

需要注意的事项:

  • 数据不能与当前数据重叠。您必须对值进行分区。新数据不能在当前分区的数据中交织在一起。如果删除数据,则必须删除整个分区。你不会有WHERE子句。

  • 如果您在生产数据库上执行此操作并希望限制表上的锁定,请使用“ONLINE = ON”创建索引。

步骤概述:

  • 添加记录

    • 对要添加记录的表进行分区(为新数据保留空白分区)。不要忘记对所有索引进行分区。
    • 使用完全相同的结构(键,数据类型等)创建新表。
    • 向新表添加约束以限制该数据,使其适合旧表中的空白分区。
    • 将新行插入新表格。
    • 添加索引以匹配旧表。
    • 使用旧表的空白分区交换新表。
    • 如果您愿意,请取消对旧表的分区。
  • 删除记录

    • 将表分区为集合,以便您要删除的数据本身都在分区上(这可能是许多不同的分区)。
    • 使用相同的分区创建一个新表。
    • 将包含您要删除的数据的分区交换到新表。
    • 如果您愿意,请取消对旧表的分区。