2010-01-04 2 views
0

Моя проблема заключается в том, что мне нужно удалить около 60M записей из таблицы, не вызывая взаимоблокировки с другими процессами, использующими эту таблицу. На этом этапе я почти закончил удаление записей, используя цикл while, который обрабатывает только 1M записей за один раз, однако это берется весь день.Эффективное удаление SQL Server 2005

Q1: Каков оптимальный способ удаления большого количества данных из таблицы, сохранения таблицы в Интернете и минимального воздействия на другие ресурсы, которые должны использовать эту таблицу в MS SQL Server 2005?

Q2: Есть ли способ реализовать блокировку отдельных строк (а не блокировку таблицы) в SQL Server, как в Oracle? (Примечание, отвечающее на это, может ответить на вопрос Q1).

A2: Так как @Remus Rusanu сообщил мне, что есть способ сделать row level locking с удалением.

ответ

2

См. Это thread, оригинальный плакат фактически провел несколько тестов и опубликовал наиболее эффективный метод. MVP изначально перешел с возможностью фактически вставить данные, которые вы хотите сохранить в таблицу temp, а затем обрезать исходную таблицу и повторно вставить.

+0

Мне это нравится. В следующий раз, когда я должен сделать что-то вроде этого, я должен сделать это. –

+0

Первоначально мы планировали перенести записи на новую таблицу. Однако тесты показали, что время перестроить индексы с нуля будет слишком высоким. –

+0

Я делаю это регулярно, и это работает как шарм. Гораздо лучше, чем удаление большого количества строк. –

1

Я только что недавно сделал что-то подобное. Я просто создал задание SQL Server, которое каждые 10 минут удаляло миллион строк. Код следует

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; 
DELETE TOP 1000000 FROM BIG_TABLE WHERE CreatedDate <= '20080630' 

У этой таблицы было около 900 миллиметров строк для начала. Не заметил существенных проблем с производительностью.

+0

Итак, скрипт, который я написал, удаляет данные из большого количества таблиц (большинство из них имеют только одну запись в них), мне нужно объявить это один раз после BEGIN TRAN или мне нужно поместить его по каждому оператору delete в моем скрипте ? –

+0

Перед началом операции НАЧАЛО. Например, УСТАНОВЛЕННЫЙ УРОВЕНЬ ИЗОЛЯЦИИ КОМПЛЕКТАЦИИ НЕОБХОДИМО; DELETE ТАБЛИЦА А DELETE TABLE B COMMIT TRAN SET Уровень изоляции транзакций YOUR_ORIGINAL_LEVEL –

1

Наиболее эффективным способом является переключение разделов, см. Transferring Data Efficiently by Using Partition Switching. Недостатком является то, что для планирования разделов требуется планирование вперед.

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

Что касается Q2, SQL Server имел блокировку уровня строки с середины 90-х годов, я не знаю, что вы на самом деле спрашиваете.

+0

Если и downvote, объяснить, почему –

+0

SQL-сервер имеет уровень блокировки страницы не блокировка строк уровня. http://download.oracle.com/docs/cd/E12151_01/doc.150/e12156/ss_oracle_compared.htm –

+2

Я бы рекомендовал вам придерживаться документации MSDN для функций SQL Server, а не Oracle.См. Http://msdn.microsoft.com/en-us/library/ms189849.aspx и http://msdn.microsoft.com/en-us/library/ms189286.aspx для доступных режимов блокировки в SQL Server. Даже маркетинговый документ Oracle, на который вы ссылаетесь, говорит: «SQL 7.0 имеет блокировку на уровне строк», и это относится к SQL 7, начиная с 1997 года. Текущий вариант - 10,5 (2008 R2), а блокировка на уровне строк была стандартным modus operandi для SQL Server, поскольку SQL 2000 (т.е. SQL 8.0). Принятие решения на основе такой устаревшей информации не может привести к хорошим решениям. –