我有一個在Postgres 8.4上運行約5秒的查詢。它從加入其他表格的視圖中選擇數據,但也使用窗口函數(即,)。封裝Postgres查詢視圖使其非常緩慢
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))
如此看來,在緩慢的情況下,它試圖將窗函數首先適用於所有數據,然後將其過濾,這可能是問題。不過,我不知道爲什麼會這樣做。
+1,但我強烈懷疑你需要填寫'...'部分,然後纔能有人診斷髮生了什麼。 – Edmund 2010-08-20 00:35:11
我可以,但查詢如果相當複雜,我不得不解釋所有相關表的樣子。我的問題更多的是關於這個具體查詢的通用解決方案:是否有辦法告訴Postgres「查看」一個視圖並使用相同的查詢計劃,就像我直接輸入底層SQL一樣。 – EMP 2010-08-20 01:28:00
發佈查詢執行計劃? EXPLAIN SELECT ... – 2010-08-20 01:28:56