Postgresql

使用 postgresql_fdw 手動執行特定的遠端查詢

  • January 9, 2016

在 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 ,就像您已經提到的那樣。

引用自:https://dba.stackexchange.com/questions/77306