从SQL Server中删除大量行 – 以高效且非锁定的方式

前端之家收集整理的这篇文章主要介绍了从SQL Server中删除大量行 – 以高效且非锁定的方式前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在编写一个过程来删除n天以上的几个表中的所有行.

一个死的简单查询很容易编写

DELETE FROM [myTable] 
WHERE [Created] < GETDATE()-30

一个问题是日期字段上没有索引 – 我可以添加一个,但我正在通过执行以下操作来解决它:

SELECT @var = MAX([ID]) FROM myTable WHERE Created < GETDATE()-30; 
DELETE FROM myTable WHERE ID < @var

这看起来像是一种可接受的方法吗?

问题是表格很大,而且每次运行时此查询可能会删除数十万行.

在一个(稍微慢一点)的测试服务器上运行它需要一个小时左右,并从其他进程中读取/写入它来杀死该表.

我不介意花一些时间来运行(虽然更快更好) – 但我不能让它在运行时锁定表一小时,因为有持续的读/写正在进行(主要是写) .

我的DB知识非常基础,因为我是编码器而不是dba.

有人能给我一个很好的方法来执行这项任务 – 以最有效的方式.

解决方法

您正在寻找的是基于分区的滑动窗口: How to Implement an Automatic Sliding Window in a Partitioned Table on SQL Server 2005.按日对表进行分区,您可以在午夜的单个分区切换操作中有效地停止一整天.分区开关基本上是瞬时的.

如果你想要一个开销略低的解决方案(分区会产生严重的后果并在整个应用程序中产生波动,特别是当索引必须对齐时,这是快速切换操作的要求),那么你必须按照设计来设计你的模式.这个操作.有99.99%的置信度,我可以说myTable最左边的聚类键必须是Created字段.这将允许有效的批量删除(从myTable删除top(2500)Created< ...).您希望对其进行批处理的原因有很多(一次最多2500个),最重要的是您必须避免锁定升级,并且必须将任何单个事务的大小保持在合理的限制范围内.

猜你在找的MsSQL相关文章