Bulk DELETE на SQL Server 2008 (Есть ли что-нибудь вроде Bulk Copy (bcp) для удаления данных?)
Есть ли какое-либо решение для массового удаления в SQL Server?
Я не могу использовать TRUNCATE, потому что я хочу использовать WHERE для ограничения строк в действии.
Есть ли что-нибудь вроде Bulk Copy (bcp) для удаления данных?
Ответы
Ответ 1
Нет.
Вы хотите DELETE с предложением WHERE: это стандартный SQL.
Что вы можете сделать, так это пакетное удаление:
SELECT 'Starting' --sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
DELETE TOP (xxx) MyTable WHERE ...
Или если вы хотите удалить очень высокий процент строк...
SELECT col1, col2, ... INTO #Holdingtable
FROM MyTable WHERE ..opposite condition..
TRUNCATE TABLE MyTable
INSERT MyTable (col1, col2, ...)
SELECT col1, col2, ... FROM #Holdingtable
Ответ 2
Вы можете сделать пару вещей, если хотите удалить часть своей таблицы, а не TRUNCATE
.
вы можете выбрать часть таблицы в новую таблицу, а затем переключить два так:
SELECT *
INTO tmp_MyTable
FROM MyTable
WHERE Key='Value'
IF @@ROWCOUNT > 0
BEGIN
EXEC sp_rename MyTable, old_MyTable, NULL
EXEC sp_rename tmp_MyTable, MyTable, NULL
TRUNCATE old_MyTable
END
Во-вторых, если вы используете Partitioning, вы можете создать идентичную (пустую) таблицу на той же схеме разделов.. и если таблица разделена в соответствии с вашей логикой архивирования/очистки, вы можете переместить один блок раздела из своего главной таблицы в новую таблицу, а затем усечь новую таблицу. Например:
ALTER TABLE MyTable
SWITCH PARTITION 15 TO purge_MyTable PARTITION 2
GO;
TRUNCATE TABLE purge_MyTable
Ps.
Разделы доступны в SQL 2005/08 Ent.
Надеюсь, это поможет!
Ответ 3
Sychare Jedko,
Преимущество TRUNCATE заключается в том, чтобы избежать регистрации каждого отдельного удаления в файле журнала. оператор TRUNCATE создаст единую запись (в журнале) для всей партии.
Ответ 4
Просто столкнулся с подобной проблемой, работая над промежуточной таблицей, у которой были проблемы с масштабированием с правильными блокировками.
Поскольку соответствующая таблица упоминается только в одном месте для нас, мы просто заменили эту ссылку запросом для имени динамической таблицы, которое создается с помощью "select into", аналогичного тому, что предлагалось gbn.
Это поддерживается, поскольку промежуточная таблица упоминается только в одном месте в коде, а расход дополнительного вызова базы данных вместе с созданием таблицы оправдан в контексте складирования. Если у вас всего несколько сотен записей или многократно ссылаются на таблицу в вашем коде, тогда этот подход может не работать.
Ответ 5
При обработке миллиона строк я предпочитаю иметь инструкцию WHERE и использовать SELECT INTO в таблице копирования, удалять исходную таблицу и переименовывать копию (обратно к исходному имени).
Хотя, у вас должны быть такие вещи, как (FK) ключи, ограничения и т.д. Но используя этот метод, вы избегаете размера журнала badazz, и вы избегаете огромного использования времени для удаления в кусках.
/Snedker
Ответ 6
проверьте это