0

我有几张表,它们都有大约:500 万行,每个表都有 Active 列。我想从 Active = 0.using delete 需要大量时间的所有表中删除数据,而且我无法截断该表,因为它具有外键约束和标识字段。

有没有一种有效的方法来做到这一点?

4

6 回答 6

1

我仍然是一名 JR 程序员,但如果你要删除一些非常大的东西,而它只有一个字段(Active = 0),但这需要很长时间。在我眼里你有两个选择。

1)运行该查询,并耐心等待。

2)找到另一种方法将查询分成几个较小的查询。例如,active = 0 和以 AG 开头的用户名,然后是 HP 的用户名,以此类推。(伪示例,但你明白我希望的想法吗?)

于 2012-05-16T18:16:07.563 回答
0

您还可以删除块中的行

http://www.java2s.com/Tutorial/SQLServer/0400__Transact-SQL/DeletingRowsinChunks.htm

于 2012-05-16T18:14:28.947 回答
0

要记住的另一件事是复制。如果表很大,并且您必须删除很多记录,您可能希望在发生如此多的删除之后放置一个等待延迟,这样您就不会泛滥复制命令。

于 2012-05-16T21:03:37.307 回答
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 的行是“昂贵的”(即,这是一个非索引选择),您可能需要先将这些行的主键选择到临时表中,然后根据连接从表中删除临时表。

于 2012-05-16T22:05:31.023 回答
0

试试这个。

这个想法是复制表,重新创建表,并复制活动数据

  1. SSMS > 右键单击​​表并选择 Script table as - Create To - New Window (不要执行)
  2. 将现有表重命名为另一个名称。
  3. 在第 1 步运行脚本
  4. 从重命名表运行复制脚本到新创建的表

    插入新表 select * from RenamedTable where active=1

  5. 删除重命名表

让我知道情况如何。

于 2012-05-16T23:31:57.543 回答
-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
于 2012-05-16T18:20:06.850 回答