我需要在不增加CPU SQL服务器的情况下删除大量数据。
以下是我的查询示例。子查询返回大约999K行,我需要逐个删除。但问题是它首先删除千位并给出错误
Msg -2, Level 11, State 0, Line 0
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
DECLARE @i INT
CREATE TABLE #TempListingTable (ID INT Primary Key IDENTITY(1,1), ListingID INT)
DECLARE @numrows INT
DECLARE @ListingID INT
INSERT #TempListingTable
SELECT T1.ListingID
FROM Table T1 WITH(NOLOCK)
LEFT OUTER JOIN Table T2
ON T1.ID = T2.ID
WHERE T1.ID IS NULL AND T1.ID IS NOT NULL
SET @i = 1
SET @numrows = (SELECT COUNT(*) FROM #TempListingTable)
IF @numrows > 0
WHILE (@i <= (SELECT MAX(ID) FROM #TempListingTable))
BEGIN
SET @ListingID = (SELECT ListingID FROM #TempListingTable WHERE ID = @i)
DELETE Listing WHERE ListingID = @ListingID
SET @i = @i + 1
END
如果我在子查询中删除,就像你在下面看到的那样CPU上升并提供超时
DELETE T1
FROM Table T1 WITH(NOLOCK)
LEFT OUTER JOIN Table T2
ON T1.ID = T2.ID
WHERE T1.ID IS NULL AND T1.ID IS NOT NULL
在这种情况下,最好的方法是什么?
答案 0 :(得分:1)
您需要首先修复您的sql,它应该永远不会删除任何行,因为T1.ID为null且T1.ID不为null。解决这个问题并使用类似的东西
WHILE 1 = 1
BEGIN
DELETE TOP 1000 T1
FROM Table T1 WITH(NOLOCK)
LEFT OUTER JOIN Table T2
ON T1.ID = T2.ID
WHERE 1 = 2
-- replace 'where' statement with a prober wherestatement.
-- I assume this is the 'where' statement you want
--WHERE T2.ID IS NULL
--AND T1.ID IS NOT NULL
IF @@ROWCOUNT = 0 BREAK
END
答案 1 :(得分:0)
这是一个.NET超时,与SQL Server无关。您不需要增加超时,您需要批量删除。如果你说它删除了第一千,然后给出了一个错误,那么让你的脚本进行删除并将其抛入proc中,使用TOP 1000或DELETE TOP(1000)将要删除的记录数限制为1000,并且然后让应用程序触发反复触发。让proc给出一个返回值(如果没有要删除的行,则为0,如果有,则为1)来控制应用程序触发proc。
否则,您能否详细说明为什么需要一次删除几乎100K行?