我使用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
答案 0 :(得分:2)
这项工作正在进行散列连接。所有其他费用都是假的。
实际出现的行数为0
,但估算的更多。
计划其余部分显示的费用基于(不正确的)估算值。
您可能会发现此效果更好。
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 t
和Entity tt
之间的加入有&lt;在它里面需要一些额外的工作。在运行删除之前,请尝试在查询窗口中运行SET STATISTICS IO ON
。我敢打赌,即使有索引,仍有相当数量的IO正在进行中。我假设你有Id, Revision
的索引?如果没有,您可以尝试添加一个。