# Переписывание: представления и RLS _Планировщик и оптимизатор · PostgreSQL Knowledge Base_ **TL;DR:** Третья стадия - система правил. Она раскрывает представления (view - это сохранённый запрос, не данные) и добавляет условия RLS. Планировщик потом сплющивает подзапрос, поэтому view сам по себе не замедляет запрос. Переписывание работает с деревом запроса между анализом и планированием (см. [query-lifecycle](/courses/postgres/kb/query-lifecycle.md)). ## Раскрытие представлений View не хранит данные - это сохранённый `SELECT`. При обращении его определение подставляется как подзапрос: ```sql CREATE VIEW svo AS SELECT * FROM flights WHERE departure = 'SVO'; SELECT flight_no FROM svo WHERE arrival = 'LED'; -- → SELECT flight_no FROM (SELECT * FROM flights WHERE departure='SVO') v -- WHERE v.arrival = 'LED'; ``` Планировщик дальше сплющивает подзапрос в один уровень и применяет оба условия к одному скану. Поэтому обращение через view и эквивалентный прямой запрос обычно дают одинаковый план - view не делает медленнее. ## Row-level security Если на таблице есть RLS-политики, переписывание добавляет к запросу условия, ограничивающие видимые строки, - автоматически и незаметно для текста запроса. ## Когда сплющивания не происходит Некоторые конструкции - оптимизационные барьеры - запрещают сплющивать подзапрос: `OFFSET 0`, `WITH ... AS MATERIALIZED`, агрегаты, оконные функции. Иногда барьер спасает от плохого плана, иногда мешает. Его используют осознанно в обе стороны. ## Команды ```sql CREATE VIEW v AS SELECT ...; ``` Сохранить запрос как представление ```sql EXPLAIN SELECT ... FROM v WHERE ...; ``` Увидеть, что view растворился в один скан ## См. также - [Жизнь запроса: пять стадий](/courses/postgres/kb/query-lifecycle.md) - [Стоимостная модель](/courses/postgres/kb/cost-model.md) - [Алгоритмы соединения: nested loop, hash, merge](/courses/postgres/kb/join-algorithms.md)