Какой запрос быстрее в контексте работы с базами данных из Node.js: DELETE или TRUNCATE?

Ответ

В контексте работы с реляционными БД (PostgreSQL, MySQL) из Node.js-приложений, TRUNCATE обычно выполняется значительно быстрее DELETE без условия WHERE.

Основные различия:

Аспект TRUNCATE DELETE (без WHERE)
Скорость Быстрее (операция уровня таблицы) Медленнее (построчное удаление)
Логирование Минимальное (только освобождение страниц) Подробное (каждая удаленная строка)
Блокировки Блокировка всей таблицы (кратковременно) Блокировка строк (может привести к долгой блокировке)
Триггеры Не вызывает триггеры ON DELETE Вызывает триггеры ON DELETE
Автоинкремент Сбрасывает счетчик (в большинстве СУБД) Сохраняет текущее значение
WHERE Не поддерживает условия Поддерживает условия

Пример использования из Node.js с PostgreSQL:

const { Client } = require('pg');

async function clearTable(tableName, useTruncate = true) {
  const client = new Client({
    connectionString: process.env.DATABASE_URL
  });

  await client.connect();

  try {
    if (useTruncate) {
      // Быстрее, но необратимо и сбрасывает sequence
      await client.query(`TRUNCATE TABLE ${tableName} RESTART IDENTITY CASCADE`);
      console.log(`Таблица ${tableName} очищена через TRUNCATE`);
    } else {
      // Медленнее, но безопаснее и вызывает триггеры
      await client.query(`DELETE FROM ${tableName}`);
      console.log(`Таблица ${tableName} очищена через DELETE`);
    }
  } catch (error) {
    console.error('Ошибка при очистке таблицы:', error.message);
    throw error;
  } finally {
    await client.end();
  }
}

// Использование
await clearTable('user_sessions', true);  // TRUNCATE
await clearTable('audit_log', false);     // DELETE (чтобы сохранить триггеры)

Когда использовать:

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

Важно для Node.js: При использовании TRUNCATE в продакшне учитывайте, что операция необратима и требует прав TRUNCATE (отдельных от DELETE). В ORM типа Sequelize или TypeORM используйте соответствующие методы (Model.truncate() vs Model.destroy({ truncate: true })).

Ответ 18+ 🔞

А, ну это же классика, ёпта! Сидишь ты такой, пишешь своё Node.js-приложение, и тут бац — надо всю таблицу в базе почистить. И встаёт вопрос, от которого у любого нормального разработчика подозрение ёбать чувствую: DELETE FROM table или TRUNCATE TABLE? А разница-то, блядь, овердохуища!

Смотри, чувак, чтобы ты не ломал голову, как Гамлет, вот тебе расклад по полочкам.

Короче, в чём суть:

Что сравниваем TRUNCATE DELETE (без всяких WHERE)
Скорость Быстрее, пиздец как! Работает с таблицей целиком, а не ковыряется в каждой строке. Медленнее, потому что каждая запись — отдельная операция.
Логи Почти не пишет. Только факт, что страницы освободил. Пишет про каждую удалённую строку. Журнал раздувается, как пузо после новогоднего застолья.
Блокировки Хватает таблицу намертво, но быстро отпускает. Может висеть долго, блокируя каждую строчку, пока всех не перетрёт.
Триггеры Не запускает триггеры ON DELETE. Просто взял и выкинул. Запускает. Если у тебя там каскадные удаления или аудит — всё сработает.
Автоинкремент Обычно сбрасывает счётчик в ноль. Начинай с чистого листа. Оставляет счётчик как есть. Удалил миллион записей — следующая будет 1000001.
Условия Не поддерживает. Всё или ничего. Можешь указать WHERE и удалить только то, что нужно.

Вот тебе пример на коленке, с PostgreSQL:

const { Client } = require('pg');

async function clearTable(tableName, useTruncate = true) {
  const client = new Client({
    connectionString: process.env.DATABASE_URL
  });

  await client.connect();

  try {
    if (useTruncate) {
      // Быстро, жёстко, необратимо. И счётчик в ноль.
      await client.query(`TRUNCATE TABLE ${tableName} RESTART IDENTITY CASCADE`);
      console.log(`Таблица ${tableName} очищена через TRUNCATE`);
    } else {
      // Медленнее, но с триггерами и возможностью отката.
      await client.query(`DELETE FROM ${tableName}`);
      console.log(`Таблица ${tableName} очищена через DELETE`);
    }
  } catch (error) {
    console.error('Ошибка при очистке таблицы:', error.message);
    throw error;
  } finally {
    await client.end();
  }
}

// Используем
await clearTable('user_sessions', true);  // TRUNCATE — выкинул кеш сессий и пофиг
await clearTable('audit_log', false);     // DELETE — чтобы триггеры на аудите отработали как надо

Так когда что брать?

  • TRUNCATE — это когда тебе да похуй на триггеры, нужно быстро выкосить тестовые данные, сбросить временную таблицу или просто терпения ноль ебать ждать. Операция «снесём всё к хуям».
  • DELETE — это когда нужна хирургия (удалить по условию), когда важны триггеры, или когда хочешь возможность откатить через WAL (журнал транзакций). Операция «аккуратно разберём».

И главное, запомни для Node.js: Если используешь какую-нибудь ORM типа Sequelize, там свои методы есть (Model.truncate() против Model.destroy({ truncate: true })). И на продакшне права TRUNCATE — это отдельная песня, их могут и не дать просто так! Так что, э, бошка думай, прежде чем чистить.