2011-12-08 158 views
0

我有一张约有550万条记录的表格。我需要根据日期删除一些记录。我的查询是这样的:删除需要很长时间

DELETE FROM Table WHERE [Date] between '2011-10-31 04:30:23' and '2011-11-01 04:30:42' 

这是关于9000行,但这一操作持续很长的时间。我如何加快速度? Date是datetime2的类型,表中有int主键聚簇。更新和删除触发器被禁用。

+2

是否有'[Date]'上的索引? –

+0

请考虑将您的专栏重命名为日期以外的内容。它从来没有**一个好主意,使用与保留字相同的列名。在某种程度上,你最终会陷入痛苦的世界。它也很懒 - 这不是日期,它是创建日期或发布日期或其他。适当命名它。 – Cruachan

回答

2

很有可能[Date]被转换为每行的字符串,导致整个表的顺序扫描。

你应该尝试铸造参数以日期来代替:

DELETE FROM Table WHERE [Date] between convert(datetime, '2011-10-31 04:30:23') and convert(datetime, '2011-11-01 04:30:42') 

此外,还要确保有上[Date]

+0

非常感谢,创建索引真的有帮助。 – viki

+0

如果系统中没有其他用户,“with(holdlock)”可能会有所帮助。 – Paparazzi

1

指数首先要确保你有约会的索引。

如果有索引检查执行计划并确保它正在使用它。请注意,并不总是使用索引是处理删除的最有效方法,因为如果删除大部分记录(经验法则超过10%),索引查找的额外开销up可以比全面扫描更大。

对于大型表格,它也非常值得确保统计数据是最新的(运行sp_updatestats),因为如果数据库对表格中的行数有不正确的理解,它会在其执行计划中做出不恰当的选择。例如,如果统计信息不正确,数据库可能会决定忽略您的索引(即使它存在),因为它认为表中的记录少得多。日期的奇怪分布可能具有相似的效果。

我可能会尝试删除日期索引,然后重新创建它。索引是二叉树,为了有效地工作,他们需要平衡。如果您的数据随着时间的推移而积累起来,那么索引可能会不平衡,查询可能需要很长时间才能找到适当的数据。这个和统计问题都应该由您的数据库维护工作自动处理,但通常会被忽略。

最后,你不要说表中是否有许多其他索引。如果存在,那么您可能会遇到数据库在进行删除以及更新索引时必须重新组织索引的问题。这有点激烈,但一种选择是在运行删除之前删除表中的所有其他索引,然后再次创建它们。

+2

好的答案。您忘记提及的另一件事是外键约束。即使您认为知道子数据已被删除,也必须对其进行检查。这会极大地减缓删除。如果你有很多FK,有时你需要小批量的删除。 – HLGEM

+0

谢谢,我在[日期]上创建了一个新索引,这有助于加快速度。在[日期]之前没有索引,因为我没有涉及[Date]的任何查询(PK上只有一个聚簇索引)。另外感谢您的额外信息,它非常有用。 – viki

+0

@HGLEM。好点,忘了那个。 – Cruachan