在PostgreSQL中将复杂查询下推到外部服务器

yk9xbfzb  于 2023-10-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(109)

我的PostgreSQL 12数据库使用postgres_fdw外部数据 Package 器设置到另一个只读PostgreSQL 12数据库。我需要从外部服务器检索复杂查询的结果。
为了简单起见,我将从the PostgreSQL window functions tutorial中的模式派生一个示例,它与我的示例具有类似的形式:

CREATE MATERIALIZED VIEW topsals AS
  SELECT depname, empno, salary, enroll_date
  FROM
    (SELECT depname, empno, salary, enroll_date,
            rank() OVER (PARTITION BY depname ORDER BY salary DESC, empno) AS pos
      FROM ext_schema.empsalary
    ) AS ss
  WHERE pos < 3
;

外部服务器中的源表ext_schema.empsalary很大,但返回的结果集要小得多,因此最好在外部执行所有查询。
当我尝试按原样执行此操作时,查询计划执行ext_schema.empsalary的全表扫描,然后在本地评估窗口函数和过滤步骤,这意味着源表中的所有行都必须从外部数据库发送。有没有办法让这种情况更有效率?

4uqofj5v

4uqofj5v1#

窗口函数不能通过postgres_fdw推送。代码如下:

/* Ignore stages we don't support; and skip any duplicate calls. */
if ((stage != UPPERREL_GROUP_AGG &&
     stage != UPPERREL_ORDERED &&
     stage != UPPERREL_FINAL) ||
    output_rel->fdw_private)
    return;

所以看起来UPPERREL_WINDOW将被绕过而不会被推。
要强制执行该问题,您需要在外部创建视图,然后在本地创建一个直接Map到该视图的外部表,而不是Map到底层表。
如果你不能这样做(因为不管是谁负责外部服务器都不会与你合作创建视图),那么剩下的选择就是使用dblink而不是postgres_fdw直接将查询文本发送到外部服务器。这并不令人愉快,但至少您可以将dblink函数调用 Package 到视图中,以抽象一些东西。

相关问题