clickhouse和pgSql跨库查询方案对比

在企业数据架构中,将 PostgreSQL(简称 PG)外部数据"联接"到 ClickHouse 查询中 是一个非常常见的需求,比如做跨库分析、数据比对、报表或中台汇聚。

ClickHouse 原生就支持多种"外部数据源访问机制",包括 PostgreSQL。下面我给你讲得 既清晰又实用👇

🧭 一、实现目标

让 ClickHouse 能直接访问 PostgreSQL 的表(或查询结果),

从而在 ClickHouse 的 SQL 查询中使用 PG 数据,就像本地表一样。

🧩 二、实现方式总览

方式 说明 场景 推荐度

✅ PostgreSQL 表引擎 ClickHouse 内置 PostgreSQL() 引擎直接访问 PG 表 最通用、官方支持 ⭐⭐⭐⭐⭐

🧰 PostgreSQL 外部字典(Dictionary) 从 PG 同步数据为 ClickHouse 字典 小数据量、维度表 ⭐⭐⭐

🔁 Materialized View + 定时同步 定期拉取 PG 数据入 ClickHouse 大数据量、离线同步 ⭐⭐⭐

🌐 通过 JDBC / ODBC 利用外部表或函数访问 PG 异构环境或特殊驱动 ⭐⭐

🚀 三、推荐方案:PostgreSQL 表引擎

✅ ClickHouse 自 21.3 版本起支持原生 PostgreSQL 引擎

1️⃣ 启用 PostgreSQL 引擎

先确认你的 ClickHouse 支持该引擎:

SELECT * FROM system.table_engines WHERE name = 'PostgreSQL';

若无结果,请在 clickhouse-server 启动参数或 config.xml 中开启:
1

并确保安装了 PostgreSQL 驱动(默认已包含)。

2️⃣ 语法示例:直接访问 PG 表

CREATE TABLE pg_orders

ENGINE = PostgreSQL

(

'host=192.168.10.12',

'database=mydb',

'user=myuser',

'password=mypass',

'orders'

);

含义:

PostgreSQL:引擎类型;

参数依次为:host, database, user, password, table_name。

现在你就可以直接查询 PG 的表啦👇

SELECT * FROM pg_orders LIMIT 10;

它会在查询时实时读取 PostgreSQL 数据(不做持久化缓存)。

3️⃣ 跨库 JOIN 示例

你可以直接与 ClickHouse 本地表进行联表查询:

SELECT c.customer_name, o.amount, o.create_time

FROM clickhouse.customers AS c

JOIN pg_orders AS o

ON c.customer_id = o.customer_id

WHERE o.create_time >= today() - 7;

🔹 ClickHouse 会在查询时从 PostgreSQL 拉取匹配数据(push-down 优化有限,但非常方便)。

4️⃣ 可选:限制数据量或分区读取

可以在查询中指定条件:

SELECT * FROM pg_orders WHERE order_date >= '2025-11-01';

或在创建时指定 schema:

CREATE TABLE pg_table

ENGINE = PostgreSQL('pg_host:5432', 'db', 'user', 'pass', 'public.orders');

🧮 四、外部表(postgresql() 函数)

如果不想长期建表,可以用函数式访问(临时查询):

SELECT *

FROM postgresql('192.168.10.12:5432', 'mydb', 'orders', 'myuser', 'mypass')

LIMIT 10;

同样可以直接 JOIN:

SELECT c.name, p.amount

FROM customers AS c

JOIN postgresql('192.168.10.12:5432', 'mydb', 'orders', 'myuser', 'mypass') AS p

ON c.id = p.customer_id;

✅ 优点:

无需创建 ClickHouse 表;

即查即用;

非常适合临时数据分析或验证。

🧰 五、使用 PostgreSQL Dictionary (维表方式)

如果你只是想同步 PG 的维度数据(如地区、用户标签),

可以使用 ClickHouse 的 外部字典(Dictionary):
user_dict 192.168.10.12 5432 myuser mypass mydb users user_id user_name String 300

然后在 SQL 中:

SELECT dictGet('user_dict', 'user_name', toUInt64(1001));

✅ 适合:

小表(几十万行以内);

缓存型维表;

低延迟场景。

📊 六、性能与注意事项

问题 说明 优化建议

查询慢 PostgreSQL 是行存储,不适合大范围扫描 仅联查小表或加过滤条件

连接超时 默认超时较短 在 config.xml 调高 connect_timeout、receive_timeout

认证失败 检查 PG 的 pg_hba.conf 是否允许远程访问

JOIN 性能低 可先同步 PG 数据到本地临时表再 JOIN 用 INSERT INTO local SELECT * FROM pg_table

网络消耗高 每次查询都会从 PG 拉取数据 可定期物化(用 MATERIALIZED VIEW 缓存)

🔧 七、实战建议

场景 推荐方案

临时分析 / 跨库 JOIN ✅ postgresql() 函数式查询

稳定跨库数据表 ✅ ENGINE = PostgreSQL 创建表

小维度表、标签表 ✅ 外部字典(Dictionary)

大数据同步分析 ✅ 定期 INSERT SELECT 同步至 ClickHouse

✅ 八、总结一句话

💡 底层原理:ClickHouse 通过 PostgreSQL 引擎或 postgresql() 函数,在查询时建立 TCP 连接,实时从 PG 读取数据并参与查询计算。

它不是复制数据,而是"实时拉取 + 按需处理"。

方案 是否实时 是否持久化 适用场景

PostgreSQL ENGINE ✅ ❌ 实时跨库联查

postgresql() 函数 ✅ ❌ 临时查询

Dictionary 定期刷新 ✅ 小表维度缓存

定期同步 ❌(准实时) ✅ 大表分析场景

相关推荐
L***86533 分钟前
MySQL中between and的基本用法、范围查询
android·数据库·mysql
2509_940880223 分钟前
CC++链接数据库(MySQL)超级详细指南
c语言·数据库·c++
l***46684 分钟前
MySQL单表存多大的数据量比较合适
数据库·mysql
l***74944 分钟前
PostgreSQL_安装部署
数据库·postgresql
m***11906 分钟前
mysql in查询大数据量业务无法避免情境下优化
数据库·mysql
我科绝伦(Huanhuan Zhou)6 分钟前
数据库故障的诊断方法与分析思路:实战经验总结
数据库
h***93668 分钟前
redis 使用
数据库·redis·缓存
j***495610 分钟前
Spring Boot 各种事务操作实战(自动回滚、手动回滚、部分回滚)
java·数据库·spring boot
0***v77710 分钟前
Redis的优势和特点
数据库·redis·缓存
2***d88511 分钟前
redis服务启动与停止
数据库·redis·缓存