什么是 FDW
FDW 是 SQL 标准 SQL/MED(SQL Management of External Data)开发的 Postgres 实现。FDW 提供了一系列统一的公共接口,使得扩展程序可以轻松地在优化、执行、扫描、更新和统计等核心部分和 Postgres 深度集成,从而可以用 SQL 语句直接查询和操作外部数据源。 例如 FDW for MySQL,用户可以像操作本地表一样地直接查询,排序、分组、过滤、Join 甚至插入和更新 MySQL 的数据。除了自己动手实现,社区已经存在了很多的 FDW 扩展,Postgres 的官方 Wiki 页面列举了一部分常见数据源的 FDW 扩展。
Greenplum 6.0 的支持状况
所有基于 Postgres 9.4 的 FDW 扩展都可以和 Greenplum 6.0 完美兼容。 默认情况下,FDW 会运行在 Master 节点上,同时 Greenplum 也可以通过选项让 FDW 运行在任意节点或者所有 Segment 节点上。 创建 FDW(以 postgres_fdw 为例):
gpadmin=# CREATE EXTENSION postgres_fdw;
CREATE EXTENSION
gpadmin=# CREATE SERVER s0 FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host '192.0.2.0', port '15432', dbname 'gpadmin');
CREATE SERVER
gpadmin=# CREATE USER MAPPING FOR gpadmin SERVER s0 OPTIONS (user 'gpadmin');
CREATE USER MAPPING
创建外部表,默认运行在 Master 节点上:
gpadmin=# CREATE FOREIGN TABLE ft1 (c1 text) SERVER s0 OPTIONS (schema_name 'public', table_name 't1');
CREATE FOREIGN TABLE
gpadmin=# EXPLAIN VERBOSE SELECT * FROM ft1 WHERE c1 = 'foo';
QUERY PLAN
-------------------------------------------------------------------
Foreign Scan on public.ft1 (cost=100.00..183.25 rows=6 width=32)
Output: c1
Remote SQL: SELECT c1 FROM public.t1 WHERE ((c1 = 'foo'::text))
Optimizer: Postgres query optimizer
(4 rows)
查询:
gpadmin=# SELECT * FROM ft1;
c1
-----
foo
bar
(2 rows)
gpadmin=# SELECT * FROM ft1 WHERE c1 = 'foo';
c1
-----
foo
(1 row)
改为运行在所有 Segment 节点上(注意此时会有一个 Gather Motion):
gpadmin=# ALTER TABLE ft1 OPTIONS (mpp_execute 'all segments');
ALTER TABLE
gpadmin=# EXPLAIN VERBOSE SELECT * FROM ft1 WHERE c1 = 'foo';
QUERY PLAN
---------------------------------------------------------------------------------
Gather Motion 3:1 (slice1; segments: 3) (cost=100.00..183.25 rows=6 width=32)
Output: c1
-> Foreign Scan on public.ft1 (cost=100.00..183.25 rows=2 width=32)
Output: c1
Remote SQL: SELECT c1 FROM public.t1 WHERE ((c1 = 'foo'::text))
Optimizer: Postgres query optimizer
(6 rows)
FDW 和 External Tables 的区别
- External Tables 支持的外部数据源很有限,并且是 Greenplum 独有的。而 FDW 可以轻松利用社区成百上千的 FDW 扩展。
- 本质上 External Tables 是基于 COPY 的,它的数据源需要先处理成 CSV 或者 TEXT 格式,效率比较低。而 FDW 直接获取数据。
- External Tables 和内核的整合有限,基本没有优化,完全没有下推。而 FDW 和内核深度整合,可以提供优化,下推和统计的功能。(目前 Greenplum 6.0 受限于 Postgres 内核版本只做到了条件下推,后续版本会陆续支持其它下推)
- External Tables 在 Greenplum 中会逐渐改用 FDW 实现。