一次执行数千个SQLServer查询

时间:2017-10-17 17:53:32

标签: sql-server

我有一个SQL Server数据库,其中存储了数百万条记录。现在,我必须不断删除大量记录,所以我在同一个执行中运行这样的数千个查询:

delete TWEET 
from TWEET 
where REQUEST_ID >= x and TWEET_ID = y and ID < z

单个查询是立即的,但将它们放在一起非常慢。

你对我有什么建议?

3 个答案:

答案 0 :(得分:3)

你可以用它。您可以每回合删除100000行。这比同时删除所有行更快。

DECLARE @RC INT = 1

WHILE @RC > 0
BEGIN

delete TOP(100000) 
from TWEET 
where REQUEST_ID >= x and TWEET_ID = y and ID < z

SET @RC = @@ROWCOUNT

END

答案 1 :(得分:0)

使用JOINed表可能是您最好的选择(见下文)。另一种选择是使用Service Broker:您将删除请求发送到SB,并且当有CPU时,某些异步进程会删除它。

------------------------------------------------------------------------
--  Create a table to hold the delete requests:
CREATE TABLE DeleteTweets (
    ID INT IDENTITY(1,1) PRIMARY KEY
    , REQUEST_ID INT
    , TWEET_ID INT
    )
GO

------------------------------------------------------------------------
--  Create an index to keep the deletions fast:
CREATE INDEX IX_DeleteTweets ON dbo.DeleteTweets (REQUEST_ID, TWEET_ID)
GO

------------------------------------------------------------------------
--  However you can put your delete requests into that table. This might
--  be part of you front-end application or via some batch process:
INSERT INTO dbo.DeleteTweets
        ( REQUEST_ID, TWEET_ID )
VALUES  ( 0, /*REQUEST_ID*/, 0 /*TWEET_ID*/)
    , ( 0, /*REQUEST_ID*/, 0 /*TWEET_ID*/)
    , ( 0, /*REQUEST_ID*/, 0 /*TWEET_ID*/)
    , ( 0, /*REQUEST_ID*/, 0 /*TWEET_ID*/)
    , ( 0, /*REQUEST_ID*/, 0 /*TWEET_ID*/)
GO

------------------------------------------------------------------------
--  Delete from the main table via JOIN:
DELETE t
FROM TWEET t
    INNER JOIN dbo.DeleteTweets dt
        ON t.REQUEST_ID = dt.REQUEST_ID
        AND t.TWEET_ID = dt.TWEET_ID
GO

------------------------------------------------------------------------
--  Once they're done, empty the table so you can re-fill with new deletion requests:
TRUNCATE TABLE dbo.DeleteTweets
GO

答案 2 :(得分:0)

- 在QUERY WINDOW 1

    DROP TABLE TWEETDEL
    GO
    DROP TABLE TWEET
    GO

    CREATE TABLE TWEET
        (ID int NOT NULL
        ,REQUEST_ID AS ID*2
        ,TWEET_ID AS ID*10  
        )   
    GO

    INSERT TWEET WITH (TABLOCKX) (ID )
    SELECT TOP 20000000 id
    FROM
          (SELECT ROW_NUMBER() OVER (ORDER BY a.id) AS id
            FROM sys.sysobjects AS a, sys.syscolumns AS b, sys.syscolumns AS c) x
    GO  

    ALTER TABLE TWEET ADD PRIMARY KEY (ID)
    GO
    SELECT IDENTITY(INT,1,1) AS TWEETDELPK, *
    INTO TWEETDEL
    FROM TWEET
    WHERE REQUEST_ID%14=0
    GO
    ALTER TABLE TWEETDEL ADD PRIMARY KEY (TWEETDELPK)
    GO
    ALTER TABLE TWEETDEL
       ADD CONSTRAINT fk101
       FOREIGN KEY (ID) REFERENCES TWEET(ID) ON DELETE CASCADE
    GO 

- 在同一个窗口

    SET NOCOUNT OFF
    DECLARE @ID INT

    CR:

    DELETE TOP (SELECT CNT FROM ##) t WITH (PAGLOCK)
    FROM TWEET AS t
    WHERE EXISTS
        (SELECT 1 FROM TWEET AS x WHERE T.ID = X.ID)

    IF @@ROWCOUNT >0 GOTO CR

- 在另一个窗口

    CREATE TABLE ## (CNT INT)

    INSERT ## SELECT 1000


    select COUNT(1) from tweetdel
    select COUNT(1) from tweet

检查是否锁定 - 如果锁定开启时间过长,升高或降低顺序

    UPDATE ## SET CNT =5000

    SELECT resource_type, resource_associated_entity_id,  
        request_status, request_mode,request_session_id,  
        resource_description   
    FROM sys.dm_tran_locks  
    WHERE resource_database_id = DB_ID()
    AND request_mode in ('x')