不用装 ClickHouse,DuckDB 也能查 ClickHouse 数据表
前两天有人问了个问题:DuckDB 怎么连 ClickHouse?
直觉方案是走 PostgreSQL 或 MySQL 桥接——ClickHouse 确实支持这两种协议。但一试就挂了:DuckDB 的 ATTACH (TYPE POSTGRES) 和 ATTACH (TYPE MYSQL) 都需要事务支持,ClickHouse 的协议实现不提供事务,直接报错。此路不通。
翻了翻 DuckDB 社区扩展目录,还真有三个方案。逐个试了一遍。
DuckDB 连接 ClickHouse 三种方案
● ● ●
chsql:HTTP 查询,最靠谱的那个
chsql 是 DuckDB 社区扩展,维护者是 lmangani 和 akvlad。周下载 13.2K,GitHub 89 星,相当活跃。
这个扩展做了两件事:
第一,100+ ClickHouse SQL 函数兼容。 装了 chsql 之后,toString、toInt8OrZero、IPv4NumToString、arrayJoin、formatDateTime 这些 ClickHouse 方言函数,在 DuckDB 里直接能用。对于从 ClickHouse 迁过来的查询,不用改 SQL。
第二,ch_scan 远程查询。 通过 HTTP 接口把 SQL 发到 ClickHouse,ClickHouse 返回 Parquet/JSON/CSV 格式,DuckDB 直接读。
安装就两行 SQL:
INSTALL chsql FROM community; LOAD chsql;
公开实例随手查:
SELECT * FROM ch_scan(
"SELECT version(), 'hello'",
"https://play.clickhouse.com",
format := 'Parquet'
);
结果:
┌────────────┬─────────┐ │ version() │ 'hello' │ │ varchar │ varchar │ ├────────────┼─────────┤ │ 24.10.2.80 │ hello │ └────────────┴─────────┘
连接你自己的 ClickHouse,带鉴权两种方式:
参数传法:
SELECT * FROM ch_scan(
"SELECT * FROM system.tables",
"http://localhost:8123",
user := 'default',
password := 'secret',
format := 'Parquet'
);
DuckDB Secret(推荐,密码不出现在查询日志里):
CREATE SECRET extra_http_headers (
TYPE HTTP,
EXTRA_HTTP_HEADERS MAP{
'X-ClickHouse-User': 'default',
'X-ClickHouse-Key': 'secret'
}
);
SELECT * FROM ch_scan(
"SELECT number * 2 FROM numbers(10)",
"http://localhost:8123"
);
format := 'Parquet' 性能最好——ClickHouse 的 Parquet 输出序列化快,DuckDB 的 Parquet 读取也高度优化。JSON 格式也能用,但慢一大截。
chsql 还模拟了几个 ClickHouse 系统表(system.tables、system.columns、system.functions),对 BI 工具兼容性有帮助。
● ● ●
chsql_native:走 TCP 原生协议,更快但不稳定
chsql_native 是 chsql 的子扩展,走 ClickHouse 原生 TCP 协议(端口 9000 / 9440 TLS),而不是 HTTP。
# 先配环境变量 export CLICKHOUSE_URL="tcp://user:pass@remote:9440/?secure=true&skip_verify=true"
INSTALL chsql_native FROM community;
LOAD chsql_native;
SELECT * FROM clickhouse_scan("SELECT version(), 'hello', 123");
绕过 HTTP 序列化层,理论吞吐更高。但它被标注为 experimental,官方提醒 "Do not use in production"。周下载 495,GitHub 16 星,适合实验环境。
额外能力:clickhouse_native('/tmp/file.clickhouse') 可以读取 ClickHouse Native 格式文件(clickhouse-local 导出的那种),但也是全表扫描,没索引。
● ● ●
ch-duckdb:用 ATTACH 语法,像连 PostgreSQL 一样
newink/ch-duckdb 是 2025 年 11 月新出的项目,走的是最接近原生 DuckDB 联邦查询的方式:ATTACH TYPE clickhouse。
ATTACH DATABASE 'ch://localhost:9000/default'
(TYPE clickhouse, USER 'default', PASSWORD 'secret');
SELECT * FROM clickhouse.system_tables LIMIT 5;
底层用 clickhouse-cpp C++ 客户端,支持 TLS、PING 验证。还有 clickhouse_scan(ad-hoc 查)和 clickhouse_query(复用已 ATTACH 的连接)两种表函数。
但目前完全不可用:
- 没发布到社区扩展仓库,必须自编译(需要
git submodule+ CMake + OpenSSL) - 测试目录是空的,零 SQLLogic 测试
- GitHub 0 星,基本没用户
只读——DDL/DML 抛 NotImplementedException。如果未来进了社区扩展仓库,这个 ATTACH 模式会是最方便的。
● ● ●
三选一
| chsql | chsql_native | ch-duckdb | |
|---|---|---|---|
| 协议 | HTTP (8123) | Native TCP (9000) | Native TCP |
| 安装 | INSTALL FROM community | INSTALL FROM community | 自编译 |
| 周下载 | 13.2K | 495 | — |
| 状态 | 稳定 | 实验性 | 极早期 |
| 读取模式 | ch_scan() 表函数 | clickhouse_scan() | ATTACH + 表函数 |
| 写入 | ❌ | ❌ | ❌ |
| 适用场景 | 生产 | 实验 | 观望 |
三个方案的共同点:都只读。目前 DuckDB ↔ ClickHouse 没有方案支持写入和 DDL,所有查询都以 SELECT 推到 ClickHouse 执行,结果拉回 DuckDB。
● ● ●
如果你只是想用 ClickHouse 风格的 SQL
chsql 不连远程 ClickHouse 也能用。100+ 宏函数在纯 DuckDB SQL 里生效:
D SELECT toString(123), toInt8OrZero('abc'), IPv4NumToString(167772161);
┌──────────────┬────────────────────┬────────────────────────────┐
│ toString │ toInt8OrZero │ IPv4NumToString │
│ varchar │ int64 │ varchar │
├──────────────┼────────────────────┼────────────────────────────┤
│ 123 │ 0 │ 10.0.0.1 │
└──────────────┴────────────────────┴────────────────────────────┘
从 ClickHouse 往 DuckDB 迁查询的时候,这个最省事。
试试 ch_scan,把你的 ClickHouse 表拉进来跑跑看。三个扩展装下来不到 30 秒。有坑有惊喜,评论区聊聊。
chsql 官方文档: duckdb.org/community_extensions/extensions/chsql
chsql GitHub: github.com/Query-farm/clickhouse-sql
ch-duckdb GitHub: github.com/newink/ch-duckdb