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

Tsql 如何在不增加服务器CPU的情况下删除大量数据?,tsql,sql-server-2008,Tsql,Sql Server 2008,我需要在不增加SQL server CPU的情况下删除大量数据 下面是我的查询示例。子查询返回大约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 CR

我需要在不增加SQL server CPU的情况下删除大量数据

下面是我的查询示例。子查询返回大约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

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

这是一个.NET超时,与SQL Server无关。你不需要增加超时时间,你需要批量删除。如果您说它删除了前1000条记录,然后给出了一个错误,那么请使用脚本执行删除操作,并将其放入一个进程,通过使用TOP 1000或delete TOP(1000)将要删除的记录数限制为1000,然后让应用程序反复启动该进程。让proc给出一个返回值(如果没有更多行要删除,则为0;如果有行,则为1),以控制触发proc的应用程序


否则,您能否详细说明为什么需要一次删除近10万行?

您需要首先修复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

过热?认真地听起来像是硬件问题。软件没有温度。在第二个子查询中,您加入T1到T2,但您没有使用T2中的任何值来过滤结果……您能避免加入T2吗?这不会使查询运行得更快吗?我们只是调用那些超时,而不是过热。我感觉T2没有过滤是一个错误。我的意思是,
其中T1.ID为NULL,T1.ID不为NULL
?不应选择任何行。Eugene,为什么需要一次删除一行?为什么它需要有一个连接?
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