В чем разница между командами DELETE и TRUNCATE в SQL?

Ответ

DELETE и TRUNCATE — это SQL-команды для удаления данных из таблицы, но их механизм, производительность и возможности кардинально различаются.

Критерий DELETE TRUNCATE
Синтаксис и цель DELETE FROM table_name [WHERE condition];
Удаляет строки выборочно (по условию WHERE).
TRUNCATE TABLE table_name;
Удаляет все строки из таблицы. Условие WHERE не допускается.
Скорость и логирование Медленнее. Каждая удаляемая строка логируется в журнале транзакций, что позволяет откат. Быстрее (часто на порядки). Удаляет данные, деаллоцируя страницы данных. Минимальное логирование.
Транзакции и откат Работает в контексте транзакции. Можно откатить командой ROLLBACK. В большинстве СУБД (MS SQL, PostgreSQL) также работает в транзакции и может быть откачен. В Oracle — DDL, авто-коммит.
Триггеры Запускает триггеры DELETE для каждой удаляемой строки. Не запускает триггеры DELETE.
Ограничения (FK) Может удалять строки, на которые есть ссылки, если каскадное удаление не настроено (вызовет ошибку). Не может удалить строки, если на таблицу ссылается ограничение FOREIGN KEY (требует его отключения).
Сброс идентификатора (IDENTITY/AUTO_INCREMENT) Не сбрасывает счетчик автоинкремента. Следующая вставка продолжит нумерацию. Сбрасывает счетчик автоинкремента до начального значения.

Практический выбор:

  • Используйте DELETE, когда нужен выборочный откатываемый удаление, или важны триггеры.
  • Используйте TRUNCATE, когда нужно быстро и полностью очистить большую таблицу, и вы уверены в своих действиях.

Ответ 18+ 🔞

Давай разберем эту парочку, а то они как близнецы, но один — хирург с скальпелем, а второй — мужик с экскаватором, который кричит "я всё снесу, ёпта!".

Смотри, оба команды — DELETE и TRUNCATE — делают, в общем-то, одно: выносят данные из таблицы на помойку. Но подход у них, блядь, как небо и земля.

DELETE — это твой аккуратный, но медлительный чиновник.

Пишешь ему: DELETE FROM users WHERE id = 666;. Он берет эту строку, заносит её в свой журнал (логирует, блять), на всякий случай, а потом удаляет. Если ты передумал — можно откатить (ROLLBACK), и он, такой: "ой, извините", — и всё вернет. Он ещё и триггеры DELETE запускает на каждой строке, типа отчитался. Но если таблица на миллион записей, он будет так с каждой возиться, и это, сука, овердохуища времени займет. И да, автоинкремент он не сбрасывает. Удалил ты запись с id=1000 — следующая будет 1001. Логично.

TRUNCATE — это десантник-разрушитель.

Его синтаксис прост, как три копейки: TRUNCATE TABLE users;. Условие WHERE ему не скажешь — он тебя не поймет и, возможно, послал бы нахуй. Его философия: "Зачем удалять строки по одной, если можно выбросить ВЕСЬ ФАЙЛ таблицы?". Он не возится с каждой записью, а просто помечает места на диске (страницы данных) как "свободные". Поэтому он быстрее на порядки. Триггеры он игнорирует — какое, нахуй, уведомление, идет зачистка!

Но тут есть хитрая жопа:

  1. Ограничения (FOREIGN KEY). Если на твою таблицу кто-то ссылается, TRUNCATE упрется и скажет "нет, мудила, сначала разберись с этими связями". Придется временно отключать ключи.
  2. Автоинкремент. После него счётчик сбрасывается в ноль. Вставишь новую запись — id будет 1. Вот это важно, ёпта!
  3. Откат. Тут зависит от СУБД. В том же PostgreSQL или SQL Server — да, TRUNCATE внутри транзакции и его можно откатить. А в Oracle, например, это операция DDL, которая сама делает коммит — и всё, поезд ушел.

Так когда что использовать?

  • DELETE — когда тебе надо выборочно почистить данные (WHERE age > 100), когда критичны триггеры, или когда ты не уверен до конца и хочешь возможность отката.
  • TRUNCATE — когда тебе надо быстро выкосить под ноль огромную таблицу (типа логов или временных данных), и ты на 146% уверен в том, что делаешь. И готов, что автоинкремент обнулится.

Проще говоря, DELETE — это "вынести мусор из квартиры, рассортировав по пакетам", а TRUNCATE — это "снести квартиру бульдозером, чтобы построить новую". Выбор за тобой, но второй способ, конечно, волнение ебать вызывает.