Самый быстрый способ удалить все данные из большой таблицы

StackOverflow https://stackoverflow.com/questions/64117

  •  09-06-2019
  •  | 
  •  

Вопрос

Мне пришлось удалить все строки из таблицы журнала, которая содержала около 5 миллионов строк.Моя первоначальная попытка состояла в том, чтобы выполнить следующую команду в анализаторе запросов:

удалить из client_log

на это ушло очень много времени.

Это было полезно?

Решение

Проверьте усечь таблицу это намного быстрее.

Другие советы

Я обнаружил, что УСЕЧЬ ТАБЛИЦУ в справочнике msdn transact-SQL.Для всех заинтересованных вот замечания:

УСЕЧЕНИЕ ТАБЛИЦЫ функционально идентично оператору DELETE без предложения WHERE:оба удаляют все строки в таблице.Но УСЕЧЕНИЕ ТАБЛИЦЫ выполняется быстрее и использует меньше ресурсов системы и журнала транзакций, чем УДАЛЕНИЕ.

Инструкция DELETE удаляет строки по одной за раз и записывает запись в журнал транзакций для каждой удаленной строки.УСЕЧЕНИЕ ТАБЛИЦЫ удаляет данные путем освобождения страниц данных, используемых для хранения данных таблицы, и только освобождения страниц записываются в журнал транзакций.

УСЕЧЕНИЕ ТАБЛИЦЫ удаляет все строки из таблицы, но структура таблицы и ее столбцы, ограничения, индексы и так далее остаются.Счетчик, используемый идентификатором для новых строк, сбрасывается на начальное значение для столбца.Если вы хотите сохранить счетчик удостоверений, используйте вместо этого команду УДАЛИТЬ.Если вы хотите удалить определение таблицы и ее данные, используйте инструкцию DROP TABLE .

Вы не можете использовать TRUNCATE TABLE для таблицы, на которую ссылается ограничение ВНЕШНЕГО КЛЮЧА;вместо этого используйте оператор DELETE без предложения WHERE .Поскольку УСЕЧЕНИЕ ТАБЛИЦЫ не регистрируется в журнале, оно не может активировать триггер.

УСЕКАЕМАЯ ТАБЛИЦА не может использоваться для таблиц, участвующих в индексированном представлении.

Существует распространенный миф о том, что TRUNCATE каким-то образом пропускает журнал транзакций.

Это недоразумение, и оно четко указано в MSDN.

Этот миф упоминается в нескольких комментариях здесь.Давайте искореним это вместе ;)

Для справки УСЕЧЬ ТАБЛИЦУ также работает на MySQL

забудьте об усечении и удалении.сохраните свои определения таблиц (на случай, если вы захотите их воссоздать) и просто используйте drop table.

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

CREATE TABLE `new_table` LIKE `table`;
RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;

truncate table является нет SQL-независимый от платформы.Если вы подозреваете, что вы мог бы когда-либо меняя поставщиков баз данных, вы можете с осторожностью относиться к их использованию.

На SQL Server вы можете использовать Truncate Table команда, которая выполняется быстрее, чем обычное удаление, а также использует меньше ресурсов.Это также приведет к возврату всех полей идентификации к исходному значению.

Недостатками truncate является то, что его нельзя использовать с таблицами, на которые ссылаются внешние ключи, и он не запускает никаких триггеров.Кроме того, вы не сможете откатить данные, если что-то пойдет не так.

Обратите внимание, что TRUNCATE также сбросит все ключи автоматического увеличения, если вы их используете.

Если вы не хотите потерять свои ключи автоматического увеличения, вы можете ускорить удаление, удаляя их наборами (например, УДАЛИТЬ ИЗ таблицы, ГДЕ id > 1 И id < 10000).Это значительно ускорит процесс и в некоторых случаях предотвратит блокировку данных.

Да, но удаление 5 миллионов строк, вероятно, займет много времени.Единственный потенциально более быстрый способ, который я могу придумать, - это удалить таблицу и создать ее заново.Конечно, это работает только в том случае, если вы хотите удалить ВСЕ данные в таблице.

усечь таблицу client_log

лучше всего, если truncate уничтожит все содержимое таблицы и индексы, а также сбросит все имеющиеся у вас начальные значения.

Предложение "Удалить и воссоздать таблицу заново", вероятно, не очень хорошее, потому что это сбивает с толку ваши внешние ключи.

Вы используете внешние ключи, верно?

Если вы не можете использовать УСЕЧЕННУЮ ТАБЛИЦУ из-за внешних ключей и / или триггеров, вы можете рассмотреть возможность:

  • удалите все индексы;
  • выполните обычное УДАЛЕНИЕ;
  • заново создайте все индексы.

Это может несколько ускорить УДАЛЕНИЕ.

Я пересматриваю свое предыдущее заявление:

Вы должны понимать, что при использовании TRUNCATE данные будут удалены, но ничего не будет занесено в журнал транзакций.Запись в журнал вот почему УДАЛЕНИЕ займет целую вечность для 5 миллионов строк.Я часто использую TRUNCATE во время разработки, но вам следует быть осторожными при использовании его в рабочей базе данных, потому что вы не сможете откатить свои изменения.Вам следует немедленно создать полную базу данных создать резервную копию после выполнения усечения, чтобы создать новую основу для восстановления.

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

От MSDN:

Инструкция DELETE удаляет строки по одной за раз и записывает запись в журнал транзакций для каждой удаленной строки.УСЕЧЕНИЕ ТАБЛИЦЫ удаляет данные путем освобождения страниц данных, используемых для хранения данных таблицы, и только освобождения страниц регистрируются в журнале транзакций.

Я просто хотел сказать, что между ними существует фундаментальная разница, и поскольку разница есть, будут приложения, в которых то или иное может оказаться неуместным.

DELETE * FROM table_name;

Преждевременная оптимизация может быть опасной.Оптимизация может означать выполнение чего-то странного, но если это сработает, вы можете захотеть воспользоваться этим преимуществом.

SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;

Что касается скорости, я думаю, это зависит от...

  • Базовая база данных:Oracle, Microsoft, MySQL, PostgreSQL, другие, пользовательские...

  • Таблица, ее содержимое и связанные с ним таблицы:

Могут существовать правила удаления.Существует ли существующая процедура удаления всего содержимого таблицы?Можно ли это оптимизировать для конкретного базового компонента database engine?Насколько сильно мы заботимся о взломе вещей / связанных данных?Выполнение УДАЛЕНИЯ может быть "самым безопасным" способом, предполагающим, что другие связанные таблицы не зависят от этой таблицы.Существуют ли другие таблицы и запросы, которые связаны / зависят от данных в этой таблице?Если мы не очень заботимся о наличии этой таблицы, использование DROP может быть быстрым методом, опять же в зависимости от базовой базы данных.

DROP TABLE table_name;

Сколько строк удаляется?Есть ли другая быстро собираемая информация, которая позволит оптимизировать удаление?Например, можем ли мы определить, что таблица уже пуста?Можем ли мы определить, существуют ли сотни, тысячи, миллионы, миллиарды строк?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top