我有几个表,所有表都有大约500万行,每个表中都有Active列。我想从Active = 0的所有表中删除数据。使用delete需要花费大量时间,而且由于它具有外键约束和标识字段,因此我无法截断表。
有一种有效的方法吗?
答案 0 :(得分:1)
我仍然是一名JR程序员,但如果你删除的东西非常大,只有一个字段(Active = 0),但这需要很长时间。你有两种选择。
1)运行该查询,并耐心等待。
2)找到另一种方法将查询分成几个较小的查询。例如,active = 0和用A-G开头的用户名,然后另一个用户名来自H-P,依此类推。 (伪示例,但你明白了我的想法?)
答案 1 :(得分:0)
答案 2 :(得分:0)
要记住的另一件事是复制。如果表很大,并且您必须删除大量记录,则可能需要在发生如此多的删除后放置waitfor delay,这样就不会使复制命令泛滥。
答案 3 :(得分:0)
declare @batchsize int 10000;
while(1=1)
begin
delete top (@batchsize)
from your_table
where isActive = 0;
if (@@rowcount = 0)
begin
break
end
end
如果找到isActive = 0的行是“昂贵的”(即非索引选择),您可能需要先将这些行的主键选择到临时表中,然后根据表格从表中删除与临时表的连接。
答案 4 :(得分:0)
试试这个。
这个想法是复制表,重新创建表,并复制活动数据
从重命名表运行复制脚本到新创建的表
从RenamedTable插入newtable select *,其中active = 1
删除RenamedTable
让我知道它是怎么回事。
答案 5 :(得分:-1)
这是我过去用来批量删除行的模板,你可以尝试一下:
-- Pick the boundaries of the data you want to delete based on
-- the Primary Key of your table
DECLARE
@StartID INT, -- Pick the appropriate datatype of your PK
@EndID INT, -- Pick the appropriate datatype of your PK
@BatchSize INT, -- Number of rows to delete in batch
@Count INT -- Temporary counter of rows deleted
SELECT TOP 1
@StartID = PrimaryKeyID
FROM
dbo.Table WITH (NOLOCK)
ORDER BY
PrimaryKeyID ASC
SELECT TOP 1
@EndID = PrimaryKeyID
FROM
dbo.Table WITH (NOLOCK)
ORDER BY
PrimaryKeyID DESC
SELECT
@BatchSize = 1000,
@Count = 1
-- You can skip this table if you like
-- The idea is to reduce the number of rows processed
-- in the batch below
CREATE TABLE #Temp
(
[ID] INT
)
WHILE @Count > 0
BEGIN
TRUNCATE TABLE #Temp
DELETE TOP (@BatchSize)
FROM
dbo.Table WITH (ROWLOCK)
OUTPUT
DELETED.PrimaryKeyID
INTO #Temp
(
[ID]
)
WHERE
PrimaryKeyID >= @StartID
AND PrimaryKeyID <= @EndID
AND Active = 0
SET @Count = @@ROWCOUNT
IF @Count = 0
BEGIN
BREAK
END
-- Move the @StartID
SELECT TOP 1
@StartID = [ID]
FROM
#Temp
ORDER BY
[ID] DESC
WAITFOR DELAY '00:01' -- delay for 1 second to allow any other queries running to process
END