我在SQL server中有一个包含136.651.894行的大表。一个月前插入了7.668.309个新行,并在一个字段中出错。在插入的那一刻,我创建了一个副本表,以确保不会发生这种情况,但没有人看到错误,我在加载过程一周后删除了表。
要删除行,我创建了一个过程,从原始表中选择每个myID的最大值(这是因为错误是我们在字段值中添加了更多的零,所以最大值是错误的,这个寄存器必须被删除),并在备份表中搜索此寄存器的myID和值,我删除该行。
例如,一行是:
ID
myId 值 其他字段......
2 2345 25948238400 其他值......
程序是:
CREATE PROCEDURE [dbo].[P_DELETE_ROWS]
AS BEGIN
DECLARE @myId VARCHAR(22)
DECLARE @value VARCHAR(20)
DECLARE c_max CURSOR
FOR
SELECT myId,max ([value]) as maxValue
FROM t1Original
group by myId
order by maxValuedesc
OPEN c_max
FETCH NEXT FROM c_max
INTO @myId ,@value
WHILE @@FETCH_STATUS = 0
BEGIN
print 'Deleting '+@myId+' y caudal '+@value +''
DELETE FROM [t1OriginalCopy] WHERE myId=@myIdAND value=@value
FETCH NEXT FROM c_max
INTO @myId,@value
END
CLOSE c_maxs
DEALLOCATE c_max
END
问题在于需要花费太多时间,现在执行时间超过1天......
如何改善此流程的效果?
答案 0 :(得分:1)
使用DENSE_RANK
代替CURSOR
。
试试这个
;WITH cte
AS (SELECT Dense_rank()OVER(partition BY myId ORDER BY value DESC) rn,*
FROM [t1OriginalCopy])
DELETE FROM cte
WHERE rn = 1
如果表(t1OriginalCopy
)将在某些其他操作中并行使用,那么您可能必须将删除拆分为批次以避免锁定
答案 1 :(得分:0)
如果您尝试一次性删除所有服务器,服务器可能会超载并且无法执行其他任务,因此请批量执行此操作,您可以停止并在必要时稍后继续。调整顶部(100)'根据服务器的管理方式更改批量大小。
Declare @rcount int=1
Select MyID, max([Value]) as maxvalue into #temp from t1Origina group by myID
while @rcount>0
begin
Delete top (100) o
FROM t1Origina o
inner join #temp t
on o.myId = t.myId and o.value = t.maxvalue
set @rcount=@@rowcount
END
Drop #temp