Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Чим DELETE відрізняється від TRUNCATE і чи можна TRUNCATE відкотити?

DELETE FROM orders видаляє рядки по одному: позначає кожен як видалений (MVCC), запускає тригери ON DELETE, перевіряє зовнішні ключі, може мати WHERE. Місце звільняється пізніше, вакуумом.

TRUNCATE orders звільняє таблицю цілком - фактично підміняє файли таблиці порожніми. Миттєво навіть на мільярді рядків, і місце повертається одразу.

Відмінності:

DELETE TRUNCATE
Умова WHERE так ні, лише вся таблиця
Швидкість на великій таблиці повільно, пропорційно кількості рядків миттєво
Тригери на рядки спрацьовують ні (є окремі ON TRUNCATE)
Блокування рядків ексклюзивне на таблицю (ACCESS EXCLUSIVE)
Лічильник identity/serial не скидає скидає з RESTART IDENTITY
Зовнішні ключі перевіряються по рядках помилка, якщо на таблицю посилаються, без CASCADE

Чи можна відкотити: у PostgreSQL так - TRUNCATE транзакційний:

BEGIN;
TRUNCATE orders;
ROLLBACK;   -- дані на місці

У MySQL TRUNCATE - DDL-команда з неявним комітом, і відкотити її не можна.

Застереження:

  • TRUNCATE бере найсильніше блокування: поки транзакція з ним не завершилася, таблицю не може читати ніхто.
  • TRUNCATE ... CASCADE очистить і всі таблиці, що посилаються на цю, - легко знищити більше, ніж планували.
  • У тестах TRUNCATE між тестами - швидкий спосіб очищення (так працює DatabaseTruncation у Laravel), але транзакція з відкатом (RefreshDatabase) ще швидша.

Докладніше в документації: TRUNCATE

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання