【问题标题】:Deadlock on Bulk Delete, need better performance批量删除死锁,需要更好的性能
【发布时间】:2017-08-08 01:06:35
【问题描述】:

我正在对一组 ID 进行批量删除,将其作为字符串发送到以逗号分隔的存储过程。我有一个函数可以将这些拆分成一个表格,以便我可以与它们进行比较。即使我有SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;,我有时也会在这个 SP 上陷入僵局。有没有更好的方法来进行批量删除,然后使用 SP 来提高性能并且没有死锁?

    DELETE FROM Game
            WHERE Id IN (
                SELECT g.Id 
                FROM Game g
                INNER JOIN [EventGame] eg ON g.Id = eg.Id
                INNER JOIN MemberEvent me ON me.EventId = eg.EventId
                WHERE 
                    eg.EventId = @EventId AND
                    g.Id IN (SELECT * FROM dbo.Split(@DeletedGameIds, ',')) AND
                    (g.[Type] = 1 OR g.[Type] IS NULL) AND 
                    me.MemberId = @MemberId
)

【问题讨论】:

  • 此删除是否在 OLTP 应用程序在线删除期间发生?
  • Game table 上的 Id 列的索引是什么?
  • 聚集索引,主键

标签: sql sql-server transactions database-deadlocks


【解决方案1】:

更好的删除方法是确定要删除的 id 列表,然后仅通过 id 执行聚集索引删除。

CREATE Table #temp (Id Int)

Insert into #temp (Id) 
SELECT Id FROM Game
            WHERE Id IN (
                SELECT g.Id 
                FROM Game g
                INNER JOIN [EventGame] eg ON g.Id = eg.Id
                INNER JOIN MemberEvent me ON me.EventId = eg.EventId
                WHERE 
                    eg.EventId = @EventId AND
                    g.Id IN (SELECT * FROM dbo.Split(@DeletedGameIds, ',')) AND
                    (g.[Type] = 1 OR g.[Type] IS NULL) AND 
                    me.MemberId = @MemberId
)

--you can do this delete in looping with batch size of 50000 records and use checkpoint
DELETE G
FROM Game G
Inner Join #temp t
ON G.ID = t.Id
--checkpoint

【讨论】:

  • 我会试试的。我应该先将我的 IDS 拆分到一个临时表中,还是在 Select 中使用它们都没有任何效果。
猜你喜欢
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 2015-10-28
  • 1970-01-01
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多