如何在不增加服务器CPU的情况下删除大量数据?

时间:2011-09-13 02:22:28

标签: tsql sql-server-2008

我需要在不增加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

在这种情况下,最好的方法是什么?

2 个答案:

答案 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行?