postgres_fdw 使用索引执行远程查询
Remote query execute with postgres_fdw, using an indexes
如前所述, postgres_fdw
无法访问索引。
解决方法是在远程服务器上创建一个视图,然后在本地服务器上为该视图创建外部 table 包装器。
但是如果我想将参数传递给我的视图怎么办?通常我会创建一个 function(myparam)
那个 RETURNS TABLE()
。但是如何通过 postgres_fdw
调用它呢?
有什么办法解决这种情况(如果不需要,最好不要使用 dblink
)?
例子
我有这样的查询要在我的远程数据库上执行:
select count(f.id_foo)
from foo f
where f.date < _my_date
如你所见,里面有一个参数_my_date
。
所以我从本地数据库创建了外国 table my_remote_server_public.my_remote_server_public_foo
和 运行 像:
select count(f.id_foo)
from my_remote_server_public.my_remote_server_public_foo f
where f.date < _my_date
但是当我这样做时 - 它会持续 2-3 分钟,因为 postgres_fdw
无法访问 foo
索引。
我考虑过在远程数据库上创建一个函数 get_foo_by_date(_my_date date)
并通过 postgres_fdw
从本地数据库调用它,但不知道是否可行...
更新
让我们假设我将正常视图作为一个外部 table 处理,里面有固定的日期。
此视图将 return 向我提供来自远程 table 的 ID 列表。
我想从远程 table 删除列出的行并将它们存档到本地。
当我这样称呼它时:
EXECUTE
'WITH rows_to_delete
AS (DELETE from my_remote_server_public_foo
WHERE id_foo
IN
(SELECT * FROM my_remote_server_public_view_of_rows_to_delete) RETURNING *)
INSERT INTO my_local_table
SELECT * FROM rows_to_delete';
它持续 5 分钟...再次因为 DELETE
查询无法访问索引...我是否也需要在这里使用 dblink
调用函数?还有其他解决方法吗?
问题不在于postgres_fdw
“无法访问索引”,而是聚合函数没有“下推”到远程服务器。
虽然聚合下推显然在 PostgreSQL 想要添加的内容列表中,但目前还没有好的方法来做到这一点。
最好的方法是使用 dblink 满足这样的要求。
在 PostgreSQL 9.6 中,postgres_fdw 中有一项新功能,您可能会滥用它来下推函数。
您必须创建一个包含该函数的扩展并将其安装在本地和远程数据库上。然后你可以把这个扩展添加到外服上的extensions
属性。如果函数是 IMMUTABLE
并且你在本地调用它,它会被推送到远程服务器。
但这丑得无法形容,我不推荐它。
作为“更新”提出的问题与问题无关,应该作为一个单独的问题提出。
这里的问题是 PostgreSQL 9.5 或更低版本
外部表之间的连接不会向下推送到远程端
逐行更新和删除操作,每个删除的行都需要往返
两者都在 PostgreSQL 9.6 中得到了改进(聚合不是这样)。
如前所述,postgres_fdw
无法访问索引。
解决方法是在远程服务器上创建一个视图,然后在本地服务器上为该视图创建外部 table 包装器。
但是如果我想将参数传递给我的视图怎么办?通常我会创建一个 function(myparam)
那个 RETURNS TABLE()
。但是如何通过 postgres_fdw
调用它呢?
有什么办法解决这种情况(如果不需要,最好不要使用 dblink
)?
例子
我有这样的查询要在我的远程数据库上执行:
select count(f.id_foo)
from foo f
where f.date < _my_date
如你所见,里面有一个参数_my_date
。
所以我从本地数据库创建了外国 table my_remote_server_public.my_remote_server_public_foo
和 运行 像:
select count(f.id_foo)
from my_remote_server_public.my_remote_server_public_foo f
where f.date < _my_date
但是当我这样做时 - 它会持续 2-3 分钟,因为 postgres_fdw
无法访问 foo
索引。
我考虑过在远程数据库上创建一个函数 get_foo_by_date(_my_date date)
并通过 postgres_fdw
从本地数据库调用它,但不知道是否可行...
更新
让我们假设我将正常视图作为一个外部 table 处理,里面有固定的日期。
此视图将 return 向我提供来自远程 table 的 ID 列表。
我想从远程 table 删除列出的行并将它们存档到本地。
当我这样称呼它时:
EXECUTE
'WITH rows_to_delete
AS (DELETE from my_remote_server_public_foo
WHERE id_foo
IN
(SELECT * FROM my_remote_server_public_view_of_rows_to_delete) RETURNING *)
INSERT INTO my_local_table
SELECT * FROM rows_to_delete';
它持续 5 分钟...再次因为 DELETE
查询无法访问索引...我是否也需要在这里使用 dblink
调用函数?还有其他解决方法吗?
问题不在于postgres_fdw
“无法访问索引”,而是聚合函数没有“下推”到远程服务器。
虽然聚合下推显然在 PostgreSQL 想要添加的内容列表中,但目前还没有好的方法来做到这一点。
最好的方法是使用 dblink 满足这样的要求。
在 PostgreSQL 9.6 中,postgres_fdw 中有一项新功能,您可能会滥用它来下推函数。
您必须创建一个包含该函数的扩展并将其安装在本地和远程数据库上。然后你可以把这个扩展添加到外服上的extensions
属性。如果函数是 IMMUTABLE
并且你在本地调用它,它会被推送到远程服务器。
但这丑得无法形容,我不推荐它。
作为“更新”提出的问题与问题无关,应该作为一个单独的问题提出。
这里的问题是 PostgreSQL 9.5 或更低版本
外部表之间的连接不会向下推送到远程端
逐行更新和删除操作,每个删除的行都需要往返
两者都在 PostgreSQL 9.6 中得到了改进(聚合不是这样)。