Postgres FDW Remote only JOIN 导致获取所有数据

Postgres FDW Remote only JOIN causes fetch all data

我正在尝试使用仅涉及远程表的 JOIN 子句从远程服务器获取数据,但它非常慢,因为计划者决定从两个表中获取所有数据并在本地合并。 当我添加 WHERE 子句时,它解决了问题并且 JOIN 在远程服务器上完全执行。

问题在小例子上是可重现的:

-- remote server
create table test
(
    id   serial
        constraint test_pk
            primary key,
    name text
);
create table test2
(
    test_id int
        constraint test2_test_id_fk
            references test (id),
    info    text
);

SELECT 查询:

SELECT "test".id  FROM "test" JOIN "test2" ON "test"."id"="test2".test_id;

EXPLAIN VERBOSE 的输出(在空表上!):

Merge Join  (cost=732.29..1388.59 rows=42778 width=4)
  Output: test.id
  Merge Cond: (test.id = test2.test_id)
  ->  Sort  (cost=366.15..373.46 rows=2925 width=4)
        Output: test.id
        Sort Key: test.id
        ->  Foreign Scan on public.test  (cost=100.00..197.75 rows=2925 width=4)
              Output: test.id
              Remote SQL: SELECT id FROM public.test
  ->  Sort  (cost=366.15..373.46 rows=2925 width=4)
        Output: test2.test_id
        Sort Key: test2.test_id
        ->  Foreign Scan on public.test2  (cost=100.00..197.75 rows=2925 width=4)
              Output: test2.test_id
              Remote SQL: SELECT test_id FROM public.test2

添加后WHERE test.id=1

Foreign Scan  (cost=100.00..198.75 rows=225 width=4)
  Output: test.id
  Relations: (public.test) INNER JOIN (public.test2)
  Remote SQL: SELECT r1.id FROM (public.test r1 INNER JOIN public.test2 r2 ON (((r2.test_id = 1)) AND ((r1.id = 1))))

我在两边都使用 AWS RDS Postgres v10.18。

这是怎么回事?如何强制在远程服务器上执行? 我没有找到任何与该问题相关的内容。

感谢您的帮助。

PostgreSQL 估计连接结果将包含 42778 行,因此它认为在本地连接表比传输大结果集更有效。

如果那个估计不正确,ANALYZE两个外部表都得到准确的统计数据,然后再试一次。请记住,不会自动分析外部表。

一般来说,在询问性能问题时,总是包含 EXPLAIN (ANALYZE, BUFFERS) 输出。

PostgreSQL 不知道它会在这些表中找到多少数据,它完全武断的猜测不是很好。

你可以这样做来帮助它:

alter server fdw options (add use_remote_estimate 'on');

规划将花费更长的时间,因为它需要多次往返于外部服务器来进行规划,但 IME 通常是值得的。

您可以改为在本地端分析外部表,以便它在本地存储统计信息。计划时间不应像 use_remote_estimate 那样受到影响。您需要偶尔重复,因为它们不会自动重新计算。我在这方面的经验很差,但那是几个版本前的版本,所以它可能有所改进。

任何一个都可以帮我修好你的复制器案例