PostgreSQL умеет замораживать часть запроса и запрещать оптимизатору его разворачивать! — 14 июня 2026 г. в 09:29:47.317
PostgreSQL умеет замораживать часть запроса и запрещать оптимизатору его разворачивать! Начиная с PostgreSQL 12 оптимизатор получил право разворачивать CTE прямо внутрь основного запроса. WITH data AS ( SELECT * FROM orders ) SELECT * FROM data WHERE user_id = 42; Такой WITH может вообще исчезнуть из плана выполнения, потому что PostgreSQL встроит его обратно в запрос. Но иногда это плохо. Например, если внутри CTE дорогой расчёт, который нельзя выполнять повторно. Тут появляется малоизвестная фича: WITH expensive AS MATERIALIZED ( SELECT * FROM huge_events WHERE created_at >= now() - interval '1 day' ) SELECT COUNT(*) FROM expensive; MATERIALIZED заставляет PostgreSQL сначала физически вычислить CTE, а потом использовать результат дальше. А обратная фича: WITH data AS NOT MATERIALIZED ( SELECT * FROM orders ) SELECT * FROM data WHERE user_id = 42; наоборот подсказывает оптимизатору агрессивно встраивать CTE обратно в запрос. Одна и та же CTE с MATERIALIZED и без него иногда отличается по производительности в десятки раз на больших объёмах данных. SQL Ready | #совет

