Добавить в корзинуПозвонить
Найти в Дзене

⚫️ CTE против TEMP TABLE

Как сделать SQL не только читаемым, но и быстрым... CTE — это классно. Читается, как рецепт. Но есть нюанс. PostgreSQL не кеширует CTE — каждый вызов = новый расчёт. Если ты используешь одну и ту же логику 3 раза — будь готов ждать. Особенно на больших объёмах. ▪️ Боль: — Запрос стал медленным — JOIN тормозит — План запроса выглядит как кошмар DBA ▪️ Решение: временная таблица — Один раз посчитал — дальше только используешь — Можно повесить индекс — Можно прогнать ANALYZE — Получаешь стабильность и прирост в скорости ▪️ TEMP TABLE — это не костыль. Это инструмент, если ты: • делаешь сложный пайп • считаешь тяжёлую метрику • хочешь предсказуемый план запроса Сценарий 1 Сценарий 2 Сценарий 3 Разбираемся, как мыслит PostgreSQL и почему «удобно» — не всегда «умно» На уровне junior CTE кажется магией: красиво, читаемо, локально. А потом ты запускаешь запрос на проде... и он не просто "думает", он медитирует. И тут приходит senior — и говорит: "А давай-ка поговорим про планировщик, кэш и ма

Как сделать SQL не только читаемым, но и быстрым...

CTE — это классно. Читается, как рецепт. Но есть нюанс.

PostgreSQL не кеширует CTE — каждый вызов = новый расчёт.

Если ты используешь одну и ту же логику 3 раза — будь готов ждать. Особенно на больших объёмах.

▪️ Боль:

— Запрос стал медленным

— JOIN тормозит

— План запроса выглядит как кошмар DBA

▪️ Решение: временная таблица

— Один раз посчитал — дальше только используешь

— Можно повесить индекс

— Можно прогнать ANALYZE

— Получаешь стабильность и прирост в скорости

▪️ TEMP TABLE — это не костыль. Это инструмент, если ты:

• делаешь сложный пайп

• считаешь тяжёлую метрику

• хочешь предсказуемый план запроса

Сценарий 1

Сценарий 2

-2

Сценарий 3

-3

Разбираемся, как мыслит PostgreSQL и почему «удобно» — не всегда «умно»

На уровне junior CTE кажется магией: красиво, читаемо, локально.

А потом ты запускаешь запрос на проде... и он не просто "думает", он медитирует.

И тут приходит senior — и говорит: "А давай-ка поговорим про планировщик, кэш и материализацию".

▪️ Что не так с CTE в PostgreSQL:

• До версии 12 — всегда как подзапрос, без оптимизации

• В новых версиях — нужно явно писать MATERIALIZED (а кто это делает?)

• Один CTE → несколько использований = столько же повторных расчётов

• Никаких тебе индексов, статистики или нормального дебага

Ты думаешь, что CTE — это «таблица внутри запроса». А движок думает: «О, ещё один подзапрос!

Давайте-ка я всё пересчитаю 5 раз». 🤷‍♂️

▪️ А вот TEMP TABLE — старый добрый друг:

• Один раз посчитал → сохранил → используешь сколько хочешь

• Добавил индекс → ускорил JOIN

• Прогнал ANALYZE → получил план запроса, который не гадание, а прогноз

• Разбил пайплайн на шаги — каждый можно проверить отдельно

▪️ Типичный пайп на проде:

1. Считал метрики → сохранил temp_metrics

2. Повесил индекс по user_id

3. Сделал JOIN с транзакциями — быстро, чётко

4. Выдал финальную витрину — и пошёл пить кофе, а не дебажить

▪️ Когда что брать:

Подход

→ 1. WITH CTE

→ 2. TEMP TABLE

Использовать когда

→ 1. Одна вставка, нужно красиво и компактно

→ 2. Много строк, повторное использование, нужен контроль

▪️ Вывод:

Хороший DE/DA не боится временных таблиц.

Он просто знает: когда CTE — это помощь, а когда — ловушка.

И если ты ловишь себя на мысли: "Кажется, движок пересчитывает всё снова..."

— это не "кажется", это происходит.

Так что выбирай не по моде, а по задаче. TEMP TABLE — взрослое решение, когда тебе важно не просто

«выполнилось», а выполнилось эффективно 💪

👉 Senior Data Analyst | #sql