以下对外部的查询在 320 万行上执行大约需要 5 秒:
SELECT x."IncidentTypeCode", COUNT(x."IncidentTypeCode")
FROM "IntterraNearRealTimeUnitReflexes300sForeign" x
WHERE x."IncidentDateTime" >= '05/01/2016'
GROUP BY x."IncidentTypeCode"
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)
当我在普通表上执行相同的查询时,它会在 0.6 秒内返回。执行计划完全不同:
SELECT x."IncidentTypeCode", COUNT(x."IncidentTypeCode")
FROM "IntterraNearRealTimeUnitReflexes300sForeign" x
WHERE x."IncidentDateTime" >= '05/01/2016'
GROUP BY x."IncidentTypeCode"
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)
Sort (cost=226861.20..226861.21 rows=4 width=4) (actual time=646.447..646.448 rows=7 loops=1)
Sort Key: "IncidentTypeCode"
Sort Method: quicksort Memory: 25kB
-> HashAggregate (cost=226861.12..226861.16 rows=4 width=4) (actual time=646.433..646.434 rows=7 loops=1)
Group Key: "IncidentTypeCode"
-> Bitmap Heap Scan on "IntterraNearRealTimeUnitReflexes300s" x (cost=10597.63..223318.41 rows=708542 width=4) …
Run Code Online (Sandbox Code Playgroud) postgresql performance postgresql-fdw postgresql-9.5 query-performance
我正在尝试设置一个具有有限权限的用户,该用户能够创建外部表。我有两个数据库,hr_db
和accounting_db
. 我已经创建了一个hr_user
用户hr_db
和一个accounting_user
用户accounting_db
。我只希望accounting_user
用户对某些hr_db
表(例如表)具有选择权限users
。为此,作为超级用户,我转到hr_db
数据库并运行:
GRANT CONNECT ON DATABASE hr_db TO accounting_user;
GRANT SELECT ON people TO accounting_user;
Run Code Online (Sandbox Code Playgroud)
我设置了一个连接hr_db
从accounting_db
使用外国数据包装:
CREATE SERVER hr_db FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host 'localhost', dbname 'hr_db', port '5432');
Run Code Online (Sandbox Code Playgroud)
然后我为accounting_user
用户添加了一个映射:
CREATE USER MAPPING FOR accounting_user SERVER hr_db
OPTIONS (user 'accounting_user', password 'secretpassword');
Run Code Online (Sandbox Code Playgroud)
密码accounting_user
与我用于从命令行登录的密码相同。这工作正常:
psql -U accounting_user -W hr_db
[enter accounting_user password] …
Run Code Online (Sandbox Code Playgroud) 似乎不允许向外部表添加外键约束。有没有其他方法可以做到这一点?我的两个表在远程服务器上有这些限制。
更具体的细节:
我真的只需要它作为注释,因为有些工具会查找 JOIN。
我在远程服务器上有两个表,我使用postgresql_fdw
's将它们添加到本地CREATE FOREIGN TABLE
。这些我在 PostgREST 中使用,自动 API 服务器使用 REFERENCES 信息进行连接。
实际上,我正在进一步增加两个CREATE MATERIALIZED VIEW
以加快查找速度 - 但遗憾的是,他们也没有任何我知道的添加 REFERENCES 信息的方法?
我愿意使用其他方法在外部 API 服务器上快速(只读)查找这些表以及外键约束将在何处工作。
在 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
Run Code Online (Sandbox Code Playgroud)
显然,发送SELECT max(col1) FROM public.table1
到远程服务器并只将一行拉回来会更有效率。
有没有办法手动执行此优化?我会对像(假设地说)这样低级的东西感到满意
EXECUTE 'SELECT max(col1) FROM public.table1' ON remote RETURNING (col1 INTEGER);
Run Code Online (Sandbox Code Playgroud)
虽然当然更喜欢更高级别的构造。
我知道我可以用 做这样的事情dblink
,但这将涉及重写大量已经使用外部表的代码,所以我不想这样做。
编辑:这是 Erwin Brandstetter 建议的查询计划:
=> explain verbose select col1 from remote_tables.table1
-> order by col1 desc nulls last limit …
Run Code Online (Sandbox Code Playgroud) 我需要我的表,另外一个是在不同的数据库(比如表链接logs
的device
数据库和表accounts
在user
分贝,无论是同一台服务器上)。因此,使用外部数据包装器我创建了一个外部表(我通过select * from accounts;
在device
成功运行的db 中运行来检查它)。
但是我仍然无法从device
db创建到外表的外键
CREATE TABLE public.logs
(
id bigint NOT NULL DEFAULT nextval('logs'::regclass),
...
account_id bigint,
...
CONSTRAINT logs_account_id_fkey FOREIGN KEY (account_id)
REFERENCES public.accounts (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
Run Code Online (Sandbox Code Playgroud)
错误信息是
ERROR: referenced relation "accounts" is not a table
********** Error **********
ERROR: referenced relation "accounts" is not a table
SQL state: 42809
Run Code Online (Sandbox Code Playgroud) 我有一个使用 RDW 的远程 postgres 表。它包含一个 JSONB 列,我使用该 JSONB 中的值作为条件WHERE
。
远程表在 JSONB 列上有一个 GIN 索引,在hostname
我用于过滤的 -attribute 上有一个索引。
EXPLAIN ANALYZE VERBOSE
SELECT
*
FROM forein_table
WHERE details->>'hostname' = 'host-xyz'
Run Code Online (Sandbox Code Playgroud)
显示“远程 SQL”不包含-WHERE
子句,并且过滤是在本地完成的。另一方面
EXPLAIN ANALYZE VERBOSE
SELECT
*
FROM forein_table
WHERE details@> '{"hostname": "host-xyz"}'
Run Code Online (Sandbox Code Playgroud)
发送“WHERE”子句,这显然要快得多。
文档说:
WHERE 子句不会发送到远程服务器,除非它们仅使用内置数据类型、运算符和函数。子句中的运算符和函数也必须是 IMMUTABLE。
->>
和之间有区别吗@>
?
有没有办法在远程表上使用WHERE details->>'hostname' = 'host-xyz'
并让它下推子句WHERE
?
(我找到了一种方法,通过创建将属性VIEW
提取hostname
为列,然后在此视图上创建远程表......但显然这不是一种非常灵活/优雅的方法)
我们使用外部数据包装器在单个 PostgreSQL RDS 上跨数据库进行查询。外部数据包装服务器需要针对将查询远程服务器的每个用户的用户映射。然而,为每个用户添加用户映射可能很容易出错。
我们所有需要查询外部数据服务器的用户都有一个共享角色,例如role_name
,在我们的 PostgreSQL 服务器上。
我们如何在用户之间共享外部数据包装服务器用户映射?
我在哪里设置postgres_fdw
. 具体我想添加use_remote_estimate
.
test=# SET use_remote_estimate=true;
ERROR: unrecognized configuration parameter "use_remote_estimate"
Run Code Online (Sandbox Code Playgroud)