我有一个SQL Server数据库,其中存储了数百万条记录。现在,我必须不断删除大量记录,所以我在同一个执行中运行这样的数千个查询:
delete TWEET
from TWEET
where REQUEST_ID >= x and TWEET_ID = y and ID < z
单个查询是立即的,但将它们放在一起非常慢。
你对我有什么建议?
答案 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')