SQL删除请求在“索引删除”中花费大量时间,即使它影响0行

时间:2013-08-23 12:21:37

标签: sql sql-server sqlperformance sql-delete

我使用MSSQL Server 2008并且我有简单条件的SQL请求,它会定期删除表中的旧记录(表中约3 mil记录)。

即使影响0行,该请求也会执行大量时间(~10秒)。

此表包含一些索引,在实际执行计划中,我看到“索引删除”操作会占用所有执行时间。

如果没有任何行受删除操作的影响,为什么SQL Server会对索引做很多工作?

更新:

请求:

delete t
from Entity t
where t.Revision <= x
AND exists (
    select 1
    from Entity tt
    where tt.Id=t.Id
    and tt.Revision > t.Revision
) 

实际执行计划XML:pastebin.com/up2E3iP1

3 个答案:

答案 0 :(得分:2)

这项工作正在进行散列连接。所有其他费用都是假的。

实际出现的行数为0,但估算的更多。

PLAN

计划其余部分显示的费用基于(不正确的)估算值。

您可能会发现此效果更好。

WITH T AS
(
SELECT *,
       ROW_NUMBER() OVER (PARTITION BY Id 
                              ORDER BY Revision DESC) AS RN
FROM Entity
)
DELETE FROM T
WHERE RN > 1
AND Revision <= 12586705

答案 1 :(得分:0)

我发现连接对子查询的性能要高得多。

试试这个

delete t
from Entity t
inner join Entity tt ON tt.Id=t.Id
where t.Revision <= x
and tt.Revision > t.Revision

另外,请确保您有Id和Revision的索引。

答案 2 :(得分:0)

不要忘记,即使您不打算删除任何记录,SQL仍需检查以确认没有要删除的记录。您在Entity tEntity tt之间的加入有&lt;在它里面需要一些额外的工作。在运行删除之前,请尝试在查询窗口中运行SET STATISTICS IO ON。我敢打赌,即使有索引,仍有相当数量的IO正在进行中。我假设你有Id, Revision的索引?如果没有,您可以尝试添加一个。