使用 postgresql_fdw 手動執行特定的遠端查詢
在 9.4b2 中,
postgresql_fdw
不知道如何在遠端表上“下推”聚合查詢,例如> explain verbose select max(col1) from remote_tables.table1; QUERY PLAN --------------------------------------------------------------------------------------------- Aggregate (cost=605587.30..605587.31 rows=1 width=4) Output: max(col1) -> Foreign Scan on remote_tables.table1 (cost=100.00..565653.20 rows=15973640 width=4) Output: col1, col2, col3 Remote SQL: SELECT col1 FROM public.table1
SELECT max(col1) FROM public.table1
顯然,發送到遠端伺服器並只拉回一行會更有效率。有沒有辦法手動執行此優化?我會對像(假設地說)這樣低級的東西感到滿意
EXECUTE 'SELECT max(col1) FROM public.table1' ON remote RETURNING (col1 INTEGER);
儘管當然首選更高級別的構造。
我知道我可以用 來做這樣的事情
dblink
,但這將涉及重寫大量已經使用外部表的程式碼,所以我不想這樣做。編輯:這是 Erwin Brandstetter 建議的查詢計劃:
=> explain verbose select col1 from remote_tables.table1 -> order by col1 desc nulls last limit 1; QUERY PLAN --------------------------------------------------------------------------------------------------- Limit (cost=645521.40..645521.40 rows=1 width=4) Output: url -> Sort (cost=645521.40..685455.50 rows=15973640 width=4) Output: col1 Sort Key: table1.col1 -> Foreign Scan on remote_tables.table1 (cost=100.00..565653.20 rows=15973640 width=4) Output: col1 Remote SQL: SELECT col1 FROM public.table1
這更好,因為它只獲取
col1
,但它仍然在網路上拖動 1600 萬行,現在它也在對它們進行排序。相比之下,應用在遠端伺服器上的原始查詢甚至不需要掃描,因為該列有一個索引。(核心查詢計劃器不夠聰明,無法為遠端伺服器上應用的修改後的查詢做到這一點,但那是次要的。)
目前,最好的選擇似乎是在遠端伺服器上創建一個視圖,該視圖封裝了需要“下推”的查詢。
postgres_fdw
很高興定義和使用由遠端視圖支持的外部表,並且視圖中的正常舊查詢優化是正確的。例如,給定CREATE VIEW id_ranges AS SELECT 'url_strings'::text AS tbl, min(url_strings.id)::bigint AS lo, max(url_strings.id)::bigint AS hi FROM url_strings UNION SELECT 'captured_pages'::text AS tbl, min(captured_pages.url)::bigint AS lo, max(captured_pages.url)::bigint AS hi FROM captured_pages UNION -- ... several more like that ...
在遠端
FOREIGN TABLE
伺服器上,在本地伺服器上同名,SELECT lo, hi FROM id_ranges WHERE tbl = 'url_strings';
現有的下推優化會將 WHERE 約束髮送到遠端,遠端將僅掃描一個表(如果可能,使用索引)並發送回單行結果。
遠端查詢優化是相當基本的:
postgres_fdw
嘗試優化遠端查詢以減少從外部伺服器傳輸的數據量。這是通過將查詢WHERE
子句發送到遠端伺服器執行,並且不檢索目前查詢不需要的表列來完成的。$$ … $$
正如您發現的那樣,我用以下內容代替的第一個想法也沒有太大的改進:
SELECT col1 FROM public.table1 ORDER BY col1 DESC NULLS LAST LIMIT 1;
目前(包括 pg 9.4),只有
WHERE
具有所有不可變函式的條件被下推。我發現這個詳盡的執行緒討論了pgsql-hackers 上的 FDW 下推狀態。您最好的選擇似乎是使用 dblink ,就像您已經提到的那樣。