Sql 删除具有大量行的表中的重复项
我有一张有1900万张唱片的桌子。我想删除重复项,但我使用的查询需要很长时间,最终连接超时 这是我正在使用的查询:Sql 删除具有大量行的表中的重复项,sql,sql-server,performance,duplicates,Sql,Sql Server,Performance,Duplicates,我有一张有1900万张唱片的桌子。我想删除重复项,但我使用的查询需要很长时间,最终连接超时 这是我正在使用的查询: DELETE FROM [TableName] WHERE id NOT IN (SELECT MAX(id) FROM [TableName] GROUP BY field) 其中,ID是主键和自动递增。 我想删除字段中的重复项 有没有比这个查询更快的替代方法 任何帮助都将不胜感激。我建议在字段中临时添加一个索引以加快速度。也许可以使用此语句删除(即使您的语句可以很好地处
DELETE FROM [TableName]
WHERE id NOT IN
(SELECT MAX(id) FROM [TableName] GROUP BY field)
其中,ID
是主键和自动递增。
我想删除字段
中的重复项
有没有比这个查询更快的替代方法
任何帮助都将不胜感激。我建议在
字段中临时添加一个索引以加快速度。也许可以使用此语句删除(即使您的语句可以很好地处理索引)
my语句生成一个应该删除的ID列表。假设将id作为主键进行索引,这可能会更快。这也应该比不在
中的性能稍好一些
with candidates as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rn
FROM [TableName]
)
delete
from candidates
where rn > 1
我建议暂时在
字段
上添加一个索引,以加快速度。也许可以使用此语句删除(即使您的语句可以很好地处理索引)
my语句生成一个应该删除的ID列表。假设将id作为主键进行索引,这可能会更快。这也应该比不在中的性能稍好一些
with candidates as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rn
FROM [TableName]
)
delete
from candidates
where rn > 1
我建议暂时在
字段
上添加一个索引,以加快速度。也许可以使用此语句删除(即使您的语句可以很好地处理索引)
my语句生成一个应该删除的ID列表。假设将id作为主键进行索引,这可能会更快。这也应该比不在中的性能稍好一些
with candidates as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rn
FROM [TableName]
)
delete
from candidates
where rn > 1
我建议暂时在
字段
上添加一个索引,以加快速度。也许可以使用此语句删除(即使您的语句可以很好地处理索引)
my语句生成一个应该删除的ID列表。假设将id作为主键进行索引,这可能会更快。这也应该比不在中的性能稍好一些
with candidates as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rn
FROM [TableName]
)
delete
from candidates
where rn > 1
创建另一个堆表并在其中插入要删除的ID。然后删除主表中的记录(存在于堆表中),每个记录块为1000-5000,以避免超时。祝你好运 创建另一个堆表,并在其中插入要删除的ID。然后删除主表中的记录(存在于堆表中),每个记录块为1000-5000,以避免超时。祝你好运 创建另一个堆表,并在其中插入要删除的ID。然后删除主表中的记录(存在于堆表中),每个记录块为1000-5000,以避免超时。祝你好运 创建另一个堆表,并在其中插入要删除的ID。然后删除主表中的记录(存在于堆表中),每个记录块为1000-5000,以避免超时。祝你好运 我的答案是对Brett Schneiders的一种改进,采用批处理方法(包括一个小的等待)来避免争用,并缓解爆炸性的日志文件增长 将初始
@batchcount
设置为您认为服务器可以处理的值——您还可以根据需要增加/减少等待时间。一旦@@ROWCOUNT=0
,循环将终止
declare @batchcount int, @totalrows int
set @totalrows = 0
set @batchcount = 10000 -- set this to some initial value
while @batchcount > 0
begin
;with dupes as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rownum
FROM [TableName]
)
delete top (@batchcount) t1
from TableName t1
join dupes c
on c.id = t1.id
and c.rownum > 1
set @batchcount = @@ROWCOUNT --record how many just got nuked
set @totalrows = @totalrows + @batchcount --track progress
print cast(@totalrows as varchar) + ' rows have been deleted' -- show progress
waitfor delay '00:00:05' -- wait 5 seconds for log writes, other queries etc
end
print语句可能不会在SSMS中的每个循环上“显示”,但您经常会看到SQL消息显示数百个已完成的迭代。。。耐心点。我的答案是对Brett Schneiders进行一次旋转,采用批处理方法(包括一个小的等待)来避免争用,并缓解爆炸性的日志文件增长 将初始
@batchcount
设置为您认为服务器可以处理的值——您还可以根据需要增加/减少等待时间。一旦@@ROWCOUNT=0
,循环将终止
declare @batchcount int, @totalrows int
set @totalrows = 0
set @batchcount = 10000 -- set this to some initial value
while @batchcount > 0
begin
;with dupes as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rownum
FROM [TableName]
)
delete top (@batchcount) t1
from TableName t1
join dupes c
on c.id = t1.id
and c.rownum > 1
set @batchcount = @@ROWCOUNT --record how many just got nuked
set @totalrows = @totalrows + @batchcount --track progress
print cast(@totalrows as varchar) + ' rows have been deleted' -- show progress
waitfor delay '00:00:05' -- wait 5 seconds for log writes, other queries etc
end
print语句可能不会在SSMS中的每个循环上“显示”,但您经常会看到SQL消息显示数百个已完成的迭代。。。耐心点。我的答案是对Brett Schneiders进行一次旋转,采用批处理方法(包括一个小的等待)来避免争用,并缓解爆炸性的日志文件增长 将初始
@batchcount
设置为您认为服务器可以处理的值——您还可以根据需要增加/减少等待时间。一旦@@ROWCOUNT=0
,循环将终止
declare @batchcount int, @totalrows int
set @totalrows = 0
set @batchcount = 10000 -- set this to some initial value
while @batchcount > 0
begin
;with dupes as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rownum
FROM [TableName]
)
delete top (@batchcount) t1
from TableName t1
join dupes c
on c.id = t1.id
and c.rownum > 1
set @batchcount = @@ROWCOUNT --record how many just got nuked
set @totalrows = @totalrows + @batchcount --track progress
print cast(@totalrows as varchar) + ' rows have been deleted' -- show progress
waitfor delay '00:00:05' -- wait 5 seconds for log writes, other queries etc
end
print语句可能不会在SSMS中的每个循环上“显示”,但您经常会看到SQL消息显示数百个已完成的迭代。。。耐心点。我的答案是对Brett Schneiders进行一次旋转,采用批处理方法(包括一个小的等待)来避免争用,并缓解爆炸性的日志文件增长 将初始
@batchcount
设置为您认为服务器可以处理的值——您还可以根据需要增加/减少等待时间。一旦@@ROWCOUNT=0
,循环将终止
declare @batchcount int, @totalrows int
set @totalrows = 0
set @batchcount = 10000 -- set this to some initial value
while @batchcount > 0
begin
;with dupes as (
SELECT id
, ROW_NUMBER() over (PARTITION by field order by id desc) rownum
FROM [TableName]
)
delete top (@batchcount) t1
from TableName t1
join dupes c
on c.id = t1.id
and c.rownum > 1
set @batchcount = @@ROWCOUNT --record how many just got nuked
set @totalrows = @totalrows + @batchcount --track progress
print cast(@totalrows as varchar) + ' rows have been deleted' -- show progress
waitfor delay '00:00:05' -- wait 5 seconds for log writes, other queries etc
end
print语句可能不会在SSMS中的每个循环上“显示”,但您经常会看到SQL消息显示数百个已完成的迭代。。。耐心点。说到重复,请查看此链接,它应该会有所帮助。说到重复,请检查此链接,它应该会有所帮助。说到重复,请检查此链接,它应该会有所帮助。说到重复,请检查此链接,它应该会有所帮助。你不需要加入
候选人
,你可以直接从候选人
中删除。你不需要加入候选人
,你可以直接从候选人
中删除。你不需要加入候选人
,你可以直接从候选人
中删除。你不需要加入候选人
,您可以直接从候选项中删除。