2015-04-20 4 views
8

У меня есть ряд функций, которые MOVE записывает из одной таблицы в другую (как правило, для архивирования данных) и задается вопросом, была ли для этого «лучшая практика» или более эффективный метод, чем я сейчас использую.SQL MOVE Записи в другую таблицу

На данный момент, я бегу что-то вроде:

INSERT INTO archive_table 
SELECT [ROWID], [COL1], [COL2] 
FROM live_table 
WHERE <criteria> 

DELETE FROM live_table 
WHERE [ROWID] IN 
(
    SELECT [ROWID] FROM archive_table 
) 

Это также рвало предупреждение о программном обеспечении производительности SQL, что запрос может вызвать подавление индекса и снижение производительности; из-за выполнения SCAN, а не SEEK.

Стоит добавить, что archive_table - это точная копия live_table, за исключением того, что мы удалили идентификатор и первичный ключ из столбца [ROWID] и что эта таблица не используется в среде «вживую», кроме того, что старые данные вставлены, как описано.

[править]

Казалось бы, что ответ от Alex обеспечивает очень простое решение для этого; комментарий об использовании триггера не разрешает проблему в этом случае, поскольку событие происходит через несколько дней, а критерии зависят от событий в течение этого периода.

DELETE 
FROM live_table 
OUTPUT DELETED.* INTO archive_table 
WHERE <criteria> 
+2

Я считаю, что предупреждение вызывается из-за того, что вы на самом деле сканируете 'archive_table' каждый раз, для каждой строки из' live_table'. ** Я думаю ** (* не уверен *) вам было бы лучше сделать DELETE с JOIN с 'archive_table', например' DELETE lt FROM live_table lt INNER JOIN archive_table at on lt.ROWID = at.ROWID' –

+5

В T- SQL DELETE + OUTPUT был бы опцией: https://msdn.microsoft.com/en-us/library/ms177564.aspx –

+0

Возможно использование триггера - установите триггер для запуска перед удалением на живой таблице, используя его для вставки строка, подлежащая удалению в таблицу архива – NickJ

ответ

0

Стоит добавить, что archive_table является точной копией live_table, за исключением того, что мы удалили личность и первичный ключ выключения колонки [ROWID] и что эта таблица не используется в пределах «живая» среда, за исключением того, что старые данные вставлены, как описано.

Я не могу определить, является ли причина, по которой вы удаляете первичный ключ из архивной таблицы, потому, что вы ожидаете, что ROWID будет повторно использоваться в live_table или нет.

Если я правильно понимаю контекст ваших данных и что вы хотите архивировать дни после завершения данных, вы можете повысить производительность запроса за счет сокращения/исключения сравнения строк, которые не будут существовать в live_table. В принципе, как только ROWID переместился из live_table в archive_table, нет причин искать его снова.

Примечание: Это предполагает, что ROWID не используются повторно в live_table и всегда увеличиваются.

INSERT INTO archive_table 
SELECT [ROWID], [COL1], [COL2] 
FROM live_table 
WHERE <criteria> 

DELETE FROM live_table 
WHERE [ROWID] IN 
(
    SELECT [ROWID] FROM archive_table WHERE [ROWID] >= (SELECT MIN(ROWID) FROM live_table) 
) 

Если ROWID повторно используются. Если в вашем наборе данных есть поле даты и времени, близкое к тому, когда запись была вживлена ​​или архивирована, ее можно использовать в качестве альтернативы ROWID. Это означало бы, что вы ищете только недавно архивированные строки для удаления из live_table, а не всего набора. Кроме того, кластеризованный индекс в файле archive_table может повысить производительность, поскольку данные будут физически упорядочены, когда вы смотрите только на хвост таблицы.

INSERT INTO archive_table 
SELECT [ROWID], [COL1], [COL2] 
FROM live_table 
WHERE <criteria> 

DELETE FROM live_table 
WHERE [ROWID] IN 
(
    SELECT [ROWID] FROM archive_table WHERE [somedate] >= DATEADD(dy,-30,GETDATE()) 
) 
+0

Извинения; Я сделал ошибку, когда я опубликовал это; это автоматически увеличивающийся «идентификатор», который удаляется из [ROWID] в архиве (а не ПК). – Sean

1

Если вам необходимо переместить большое количество записей из одной таблицы в другую, я предлагаю вам проверить возможность разметить «активную таблицу». Каждый раз вы копируете данные из одного (или более) разделов в «таблицу достижений» и отбрасываете эти разделы. Это будет намного быстрее, чем удаление записей из таблицы «онлайн».

0

Ваш фрагмент кода не включает именованную транзакцию, которая ДОЛЖНА быть первым рассмотрением.Во-вторых, создайте переменную таблицы, таблицу temp или таблицу жестких дисков, которая будет использоваться для этапа. В таблице, предназначенной для разработки, должен быть указан столбец, идентичный типу данных, в столбце идентификации из вашей исходной таблицы и этот столбец должен быть проиндексирован. Третий дизайн TSQL для заполнения промежуточной таблицы, копирования строк из исходной таблицы в таблицу назначения на основе соединения между исходным и промежуточным, а затем удалить строки из исходной таблицы на основе того же соединения, которое перемещает данные в таблицу назначения. Ниже приведен рабочий пример

--test setup below 
DECLARE @live_table table (rowid int identity (1,1) primary key clustered, col1 varchar(1), col2 varchar(2)) 
DECLARE @archive_table table (rowid int, col1 varchar(1), col2 varchar(2)) 

Insert @live_table (col1, col2) 
Values 
('a','a'), 
('a','a'), 
('a','a'), 
('a','a'), 
('b','b') 
--test setup above 

BEGIN Transaction MoveData 

    DECLARE @Staging table (ROWID int primary Key) 

    Insert @Staging 
    SELECT lt.rowid 
    FROM @live_table as lt 
    WHERE lt.col1 = 'a' 

    INSERT INTO @archive_table 
    select lt.rowid, lt.col1, lt.col2 
    FROM @live_table as lt 
    inner join @Staging as s on lt.rowid = s.ROWID 

    DELETE @live_table 
    FROM @live_table as lt 
    inner join @Staging as s on lt.rowid = s.ROWID 

COMMIT Transaction MoveData 

select * from @live_table 
select * from @archive_table 
select * from @Staging 
Смежные вопросы