我有一张大约有 550 万条记录的表。我需要根据日期从中删除一些记录。我的查询如下所示:
DELETE FROM Table WHERE [Date] between '2011-10-31 04:30:23' and '2011-11-01 04:30:42'
它大约有 9000 行,但此操作持续很长时间。我怎样才能加快速度?Date 是 datetime2 的类型,表有 int 主键聚集。更新和删除触发器被禁用。
我有一张大约有 550 万条记录的表。我需要根据日期从中删除一些记录。我的查询如下所示:
DELETE FROM Table WHERE [Date] between '2011-10-31 04:30:23' and '2011-11-01 04:30:42'
它大约有 9000 行,但此操作持续很长时间。我怎样才能加快速度?Date 是 datetime2 的类型,表有 int 主键聚集。更新和删除触发器被禁用。
很有可能 [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]
首先确保你有一个日期索引。
如果有索引,请检查执行计划并确保它正在使用它。请注意,使用索引并不总是处理删除的最有效方法,因为如果您要删除大部分记录(经验法则超过 10%),索引查找的额外开销 - up 可以大于完整扫描。
对于大表,确保统计信息是最新的(运行sp_updatestats)也是非常值得的,因为如果数据库对表中的行数有不正确的理解,它将在其执行计划中做出不适当的选择。例如,如果统计信息不正确,数据库可能会决定忽略您的索引,即使它存在,因为它认为表中的记录远少于实际记录。日期的奇数分布可能具有类似的效果。
我可能会尝试在日期删除索引然后重新创建它。索引是二叉树,为了有效地工作,它们需要平衡。如果您的数据随着时间的推移而积累,则索引可能会很不平衡,并且查询可能需要很长时间才能找到合适的数据。这和统计问题都应该由您的数据库维护工作自动处理,但它经常被忽视。
最后,您不要说表上是否还有许多其他索引。如果有,那么您可能会遇到数据库在进行删除和更新索引时必须重新组织索引的问题。这有点激烈,但一种选择是在运行删除之前删除表上的所有其他索引,然后再创建它们。