2012-05-16 3 views
0

У меня есть несколько таблиц, и все они имеют приблизительно: 5 миллионов строк, и каждая таблица имеет в ней активный столбец. Я хочу удалить данные из всех таблиц, где Active = 0.using delete занимает много времени, а также я не могу обрезать таблицу, так как она имеет ограничения внешнего ключа и поле Identity.Удаление данных из огромной таблицы

Есть ли эффективный способ сделать это?

ответ

1

Я еще программист JR, но если вы удаляете что-то действительно большой, где это только одно поле (Active = 0), но это будет занять длительное время. у вас есть 2 варианта в моих глазах.

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

ОП не указал конкретных ограничений на свою схему. Это должно было стать шаблоном ... – 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> правой кнопкой мыши на таблицу и выберите таблицу сценариев, как - Создание To - New Window (не выполнять)
  2. переименовать существующую таблицу в другое имя.
  3. запустить скрипт на шаге 1
  4. запустить копию сценария из Переименован таблицы вновь созданной таблицы

    вставки в Новая_таблица выберите * из RenamedTable где активный = 1

  5. падение RenamedTable

и дайте мне знать, как это происходит.

Смежные вопросы