我有一个名为“A”的表,它有两列,“A1”和“A2”。
我希望列“A1”中的每个唯一值在表中包含MAX 2行,如果列“A1”中的唯一值有5行,则应删除3行。
要删除的3行由“A2”列中的最低值确定。
该表包含+20万行,“A1”列中的+300000个唯一值,以及“A1”列中每个唯一值最多3000行。
我用以下查询解决了这个问题:
with excess as
(
select
id,
row_number() over(partition by A1 order by A2 desc) as rownum
from
A
)
delete from excess
where rownum > 2
我对这个查询感到满意,因为初始批处理花了8分钟,重复执行了大约20秒。
这是达到要求的最有效查询吗?
答案 0 :(得分:1)
是的,这是最有效的查询,而不是将数据复制到另一个表中,因为它是在一次针对表的运行中而不是连接回自身。我建议您使用“删除顶部(N)”并保持该数字低于5,000,如果该表的任何其他消费者。这将尝试防止锁升级升级到完整表锁。它还将释放服务器上的tlog,以便在批次之间重用。如果你一次性完成所有操作,则必须在tlog中考虑所有已删除的行,并且在语句完成之前不能重用该空间。我还建议在(A1,A2)上创建一个复合索引。
如果需要删除的行数占很大比例,则将rownum< = 2的行复制到新表中会更快。然后,删除原始表并将新表重命名为原始表。如果你有表的其他消费者和/或不想复制数据,那么这可能不是一个有效的解决方案。