А значит, идём дальше в нашем приключении по столбцам.
Мы уже научились дёшево “удалять” данные, используя методику soft delete. Но, как это обычно бывает, тут нас ждёт новый подводный камень.
Если просто начать добавлять
deleted_at IS NULL в запросы, то на больших объёмах данных мы можем не ускориться, а вполне себе замедлиться.Почему?
Потому что мы поменяли паттерн чтения, и внезапно перестали эффективно попадать в индекс.
Звучит не очень понятно — давайте разберёмся на примере.
Пример: таблица сообщений
Допустим, у нас есть таблица сообщений, и задача простая: прочитать сообщения конкретного чата, отсортированные по дате создания.
Запрос выглядит просто:
SELECT *
FROM messages
WHERE chat_id = 42
ORDER BY created_at;
Под него идеально подходит индекс:
(chat_id, created_at)Быстро, красиво, эффективно.
А теперь добавляем soft delete
Как только появляется условие:
AND deleted_at IS NULL всё начинает меняться. PostgreSQL сначала находит строки по индексу, а потом вынужден проверять deleted_at IS NULL отдельноНа больших таблицах это означает лишнюю работу, а иногда — почти последовательное сканирование.
И вот вы уже вроде как оптимизировали удаление, и сломали чтение.
Но и тут есть решение — partial index (частичный индекс)
Мы можем создать индекс только по живым строкам:
CREATE INDEX idx_messages_live
ON messages (chat_id, created_at)
WHERE deleted_at IS NULL;
Что это нам даёт:
- индекс становится меньше по размеру
- в нём лежат только актуальные данные
- чтение сообщений происходит быстро и стабильно
- планировщику проще выбрать правильный план.
Важный момент
Partial index — это не опциональная оптимизация, а обязательная часть архитектуры soft delete.
Очень частая ошибка выглядит так: «Мы внедрили soft delete, но база всё равно тормозит».
А потом выясняется, что:
- SELECT сканирует кучу удалённых строк;
- индекс есть, но он не помогает
Если коротко
Soft delete отвечает за дешёвую запись.
Partial index — за быструю выборку.
И только вместе они дают тот эффект, ради которого всё это и затевалось.
#devblogHowToDeleteInDatabase #tech