Открыть список
Как стать автором
Обновить

Комментарии 11

Запрещаем материализацию, убираем барьер:
EXPLAIN ANALYZE WITH yy AS MATERIALIZED

NOT пропущен?
да, конечно! спасибо, поправил.
Не нравится, что императивщина прорвалась в SQL (декларативный язык). Всё же решение о материализации должен принимать оптимизатор, а не разработчик. Иначе получается тот же самый хинт, только с приятным синтаксисом
НЛО прилетело и опубликовало эту надпись здесь
Гм… непонятно, «пишущие CTE исполняются всегда» относится к конкретному CTE, или ко всем CTE, когда их несколько? Иными словами, нормально работающий в 11-м
WITH cte1 AS (сложный запрос на основе нескольких копий table),
     cte2 AS (DELETE FROM table)
INSERT INTO table SELECT * FROM cte1

не приведёт ли к проблемам, если cte1 заявить как NOT MATERIALIZED?
Во всяком случае у
CREATE TABLE akina_table AS SELECT x, x AS y FROM generate_series(1,10) AS x;
EXPLAIN ANALYZE WITH
     cte1 AS (NOT MATERIALIZED) (SELECT * FROM akina_table WHERE x<2),
     cte2 AS (DELETE FROM akina_table WHERE y>9)
INSERT INTO akina_table SELECT * FROM cte1;
план одинаковый с и без NOT MATERIALIZED. Я ответил?
план одинаковый с и без NOT MATERIALIZED. Я ответил?

Вопрос был как бы не о плане. Если мы заявляем CTE1 как нематериализуемый (т.е. пусть будет кэшируемый), но при этом объём выборки великоват, чтобы поместиться в имеющуюся оперативку, то в случае без материализации его результата CTE2 почистит таблицу, и на момент выполнения основного запроса в исходной таблице просто не будет существовать данных для воспроизведения результата CTE1. Т.е. для корректного выполнения всего запроса сервер просто обязан будет начхать на наш хинт и материализовать результат CTE1. Или это будет игра «раз снапшот, два снапшот»?
Идея хорошая, но нет — работает так же, как на 11.

А как он заранее узнает, запрос пишущий или нет? Ведь запись может буть глубоко во вложенных функциях, которые вызываются через обычный SELECT в CTE.

Igor_Le Простите, пожалуйста
1) Для
WITH yy AS NOT MATERIALIZED (
SELECT * FROM xytable WHERE y > 1)
SELECT (
SELECT count(*) FROM yy WHERE x=2), (
SELECT count(*) FROM yy WHERE x=2);

верным будет что:
движок дважды обращается к индексу xytable_x_y_idx, но второе обращение заметно быстрее из-за попадания в кэш?
2) Здесь противопоставлялась явная материалиция cte и «встраивание» запроса cte в каждое использование «по месту», если я правильно понимаю.
А в чем проблема с выделением множества пересекающихся условий из выборок по cte, и переноса данных условий на этап материализации cte?
Проблема именно в «барьере» для оптимизатора. Дело не в том, попало что-то в кэш или нет: это все равно быстро, так как по индексу. В случае, когда материализация НЕ запрещена, поиск секскан, оптимизатор не может воспользоваться индексом. Он НЕ МОЖЕТ объединить условия, так как одно «внутри», а другое «снаружи». Он (по существующему дизайну) обязан сначала исполнить (точнее, исполняет, конечно, экзекьютер) внутренне, подлежащее материализации, а о внешнем он «узнает» только после этого.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Информация

Дата основания
Местоположение
Россия
Сайт
www.postgrespro.ru
Численность
51–100 человек
Дата регистрации
Представитель
Иван Панченко

Блог на Хабре