Postgres 8.4'te yaklaşık 5 saniye içinde çalışan bir sorgum var. Diğer tablolara eklenen bir görünümden veri seçer, ancak gecikme() pencere işlevini de kullanır. Encapsulating Postgres sorgu görünümünde görünümü son derece yavaşlatıyor
SELECT *, lag(column1) OVER (PARTITION BY key1 ORDER BY ...), lag(...)
FROM view1 v
JOIN othertables USING (...)
WHERE ...
kolaylık sağlamak için diğer eskisi gibi JOIN ve filtreler tüm kullanarak, basitçe
SELECT *, lag(column1) OVER (PARTITION BY key1 ORDER BY ...), lag(...)
FROM view1 v
sahiptir ve daha sonra bundan SEÇ yeni bir görünüm yarattı. Benim sürprizime bu sorgu 12 dakika içinde tamamlanmaz (ben o noktada durdu). Açıkçası Postgres, farklı bir yürütme planı seçti. Bunu yapmamak için nasıl yaparım? Orijinal plandaki gibi aynı planı kullanmak? Bir görüşün yürütme planını değiştirmemesi gerektiğini düşünürdüm ama görünüşe göre öyle.
Düzenleme: Dahası, ilk görünümün içeriğini kopyaladığım halde hala dönmemesi gerektiğini buldum.
Düzenleme 2: Tamam, sorguları göndermek için sorguyu sadeleştirdim.
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)
(bu anında döner) görüntü dışında pencere fonksiyonunu alarak ve sorguda kendisine koyarak: görünümü (bu herhangi makul bir süre içinde iade etmez) kullanarak
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))
yüzden yavaş durumunda ilk tüm verilere pencere fonksiyonu uygulamak ve daha sonra muhtemelen konu olan filtrelemek çalışıyor gibi görünüyor. Bunu neden yaptığını bilmiyorum.
+1, ancak birilerinin neler olup bittiğini teşhis edebilmesinden önce '' 'parçalarını doldurmanız gerekeceğinden şüpheleniyorum. – Edmund
Yapabilirim, ancak eğer oldukça karmaşık bir tablo varsa ve tüm ilgili tabloların neye benzediğini açıklamak zorundayım. Benim sorum bu daha ziyade bu özel sorgu için genel bir çözüm hakkında daha fazla: Postgres'e bir görünümü "gözden geçirmesi" ve aynı SQL planını doğrudan temelde SQL'e girmiş gibi kullanmasını söylemenin bir yolu var. – EMP
Sorgu yürütme planlarını yayınlama? EXPLAIN SELECT ... –