2012-05-16 119 views
0

我有幾張表,它們都有大約500萬行,每個表中都有Active列。我想從Active = 0的所有表中刪除數據。使用刪除需要很多時間,並且由於它具有外鍵約束和標識字段,因此我無法截斷表。從巨大的表中刪除數據

有沒有一種有效的方法來做到這一點?

回答

1

我還是JR程序員,但如果要刪除一些真正的大的地方只有一個字段(活動= 0),但會需要很長時間。你在我眼中有兩種選擇。

1)運行該查詢,並保持耐心。

2)找到另一種方式將查詢劃分爲幾個較小的查詢。比如,active = 0和用戶名稱以A-G開頭,然後另一個用戶名爲H-P等等。 (?假的例子,但你的想法,我希望)

-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 
+0

只有當主鍵上的要刪除的數據範圍連續時,這纔會起作用。一個非常特殊的場景! –

+0

OP尚未在其模式中真正指定任何特定約束。這是爲了成爲一個模板... – diaho

0

另一件事要記住是複製。如果表很大,並且您必須刪除大量記錄,那麼在發生如此多的刪除操作後,您可能希望放置一個waitfor delay,這樣您就不會氾濫複製命令。

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是「貴」(即這是一個非索引選擇),您可以先選擇那些行的主鍵到一個臨時表,然後做從刪除您的表基於與臨時表的連接。

0

試試這個。

的理念,是複製表,重新創建表,並複製活躍的數據

  1. SSMS>右鍵單擊該表並選擇Script表作爲 - 創建要 - 新窗口(不執行尚未)
  2. 將現有表重命名爲另一個名稱。
  3. 上步驟運行腳本1
  4. 運行副本腳本從更名錶到新創建的表

    插入件插入newtable的SELECT * FROM RenamedTable active = 1的

  5. 降RenamedTable

讓我知道它是怎麼回事。