alitrack

不用装 ClickHouse,DuckDB 也能查 ClickHouse 数据表

前两天有人问了个问题:DuckDB 怎么连 ClickHouse?

直觉方案是走 PostgreSQL 或 MySQL 桥接——ClickHouse 确实支持这两种协议。但一试就挂了:DuckDB 的 ATTACH (TYPE POSTGRES) 和 ATTACH (TYPE MYSQL) 都需要事务支持,ClickHouse 的协议实现不提供事务,直接报错。此路不通。

翻了翻 DuckDB 社区扩展目录,还真有三个方案。逐个试了一遍。

DuckDB 连接 ClickHouse 三种方案

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 模式会是最方便的。

● ● ●

三选一

chsqlchsql_nativech-duckdb
协议HTTP (8123)Native TCP (9000)Native TCP
安装INSTALL FROM communityINSTALL FROM community自编译
周下载13.2K495—
状态稳定实验性极早期
读取模式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