У меня есть запрос, который выполняется около 5 секунд на Postgres 8.4. Он выбирает данные из представления, объединенного с некоторыми другими таблицами, но также использует оконную функцию lag () , т. Е.
SELECT *, lag(column1) OVER (PARTITION BY key1 ORDER BY ...), lag(...)
FROM view1 v
JOIN othertables USING (...)
WHERE ...
Для удобства я создал новый вид, который просто имеет
SELECT *, lag(column1) OVER (PARTITION BY key1 ORDER BY ...), lag(...)
FROM view1 v
, а затем ВЫБРАТЬ из этого, используя все другие СОЕДИНЕНИЯ и фильтры, как и раньше. К моему удивлению, этот запрос не завершается за 12 минут (я остановил его в тот момент). Очевидно, Postgres выбрал другой план выполнения. Как мне заставить его этого не делать, т.е. использовать тот же план, что и в исходном запросе? Я бы подумал, что представление не должно изменять план выполнения, но, видимо, это так.
Редактировать: более того, я обнаружил, что даже если я скопирую содержимое первого представления во второе, оно все еще не возвращается.
Редактировать 2: ОК, я достаточно упростил запрос, чтобы опубликовать планы.
Использование представления (это не возвращает в разумные сроки):
Subquery Scan sp (cost=5415201.23..5892463.97 rows=88382 width=370)
Filter: (((sp.ticker)::text ~~ 'Some Ticker'::text) AND (sp.price_date >= '2010-06-01'::date))
-> WindowAgg (cost=5415201.23..5680347.20 rows=53029193 width=129)
-> Sort (cost=5415201.23..5441715.83 rows=53029193 width=129)
Sort Key: sp.stock_id, sp.price_date
-> Hash Join (cost=847.87..1465139.61 rows=53029193 width=129)
Hash Cond: (sp.stock_id = s.stock_id)
-> Seq Scan on stock_prices sp (cost=0.00..1079829.20 rows=53029401 width=115)
-> Hash (cost=744.56..744.56 rows=29519 width=18)
-> Seq Scan on stocks s (cost=0.00..744.56 rows=29519 width=18)
Вывод оконной функции из представления и вставка в сам запрос (это возвращает мгновенно):
WindowAgg (cost=34.91..34.95 rows=7 width=129)
-> Sort (cost=34.91..34.92 rows=7 width=129)
Sort Key: sp.stock_id, sp.price_date
-> Nested Loop (cost=0.00..34.89 rows=7 width=129)
-> Index Scan using stocks_ticker_unique on stocks s (cost=0.00..4.06 rows=1 width=18)
Index Cond: ((ticker)::text = 'Some Ticker'::text)
Filter: ((ticker)::text ~~ 'Some Ticker'::text)
-> Index Scan using stock_prices_id_date_idx on stock_prices sp (cost=0.00..30.79 rows=14 width=115)
Index Cond: ((sp.stock_id = s.stock_id) AND (sp.price_date >= '2010-06-01'::date))
Так что кажется, что в медленном случае он пытается применить оконную функцию сначала ко всем данным, а затем отфильтровать их, что, вероятно, является проблемой. Я не знаю, почему он это делает.