跳转到主要内容

概述

本教程基于 [ClickHouse 教程],但其中所有查询均通过 pg_clickhouse 运行。

启动 ClickHouse

首先,如果你还没有 ClickHouse 数据库,请先创建一个。快速开始的一种方式 是使用 Docker image:

创建表

让我们参考[ClickHouse 教程],使用 The New York City taxi 数据集创建一个简单的数据库:

添加数据集

然后导入数据:
确认可以查询后,退出客户端:

安装 pg_clickhouse

PGXNGitHub 构建并安装 pg_clickhouse。或者使用 [pg_clickhouse image] 启动一个 Docker 容器;该镜像只是在 Docker Postgres image 中加入了 pg_clickhouse:

连接 pg_clickhouse

现在连接到 Postgres:
接着创建 pg_clickhouse:
使用主机名、端口和 ClickHouse 数据库的数据库名称来创建 foreign server。
这里我们选择使用二进制驱动,它使用 ClickHouse 二进制 协议。你也可以使用 “http” 驱动,它使用 HTTP 接口。 接下来,将 PostgreSQL 用户映射到 ClickHouse 用户。最简单的做法 就是将当前 PostgreSQL 用户映射到 foreign server 的远程用户:
你也可以指定 password 选项。 现在,添加 taxi 表,只需将远程 ClickHouse 数据库中的所有表导入到一个 Postgres schema 中:
现在,这张表应该已经导入成功了:在 psql 中,使用 \det+ 查看:
成功!使用 \d 查看所有列:
现在来查询该表:
注意这个查询执行得有多快。pg_clickhouse 将整个 查询 (包括 COUNT() 聚合) 都下推,因此查询会在 ClickHouse 上执行,并且只 向 Postgres 返回一行结果。使用 EXPLAIN 查看:
请注意,“Foreign Scan” 出现在执行计划的根节点,这意味着 整个查询都已下推到 ClickHouse。

分析数据

运行一些查询来分析数据。参考以下示例,或尝试 自行编写 SQL 查询。
  • 计算平均小费金额:
  • 按乘客人数计算平均费用:
  • 按街区统计每天的接载次数:
  • 计算每次行程的时长 (单位为分钟) ,然后按 行程时长对结果分组:
  • 显示各街区在一天中每个小时的接载次数:
  • 将显示时区设为纽约时区,并检索前往拉瓜迪亚或 JFK 机场的行程:

创建字典

在你的 ClickHouse 服务中创建一个与表关联的字典。该表和字典基于一个 CSV file,其中包含纽约市每个街区的一行数据。 这些街区映射到纽约市五个行政区的名称 (Bronx、Brooklyn、Manhattan、Queens 和 Staten Island) ,以及 Newark Airport (EWR)。 下面是所用 CSV file 的部分内容,以表格形式展示。文件中的 LocationID 列映射到 trips 表中的 pickup_nyct2010_giddropoff_nyct2010_gid 列:
LocationIDBoroughZoneservice_zone
1EWRNewark AirportEWR
2QueensJamaica BayBoro Zone
3BronxAllerton/Pelham GardensBoro Zone
4ManhattanAlphabet CityYellow Zone
5Staten IslandArden HeightsBoro Zone
  1. 仍在 Postgres 中,使用 clickhouse_raw_query 函数创建一个名为 taxi_zone_dictionary 的 ClickHouse 字典,并通过 S3 中的 CSV file 为该字典填充数据:
LIFETIME 设置为 0 会禁用自动更新,从而避免对我们的 S3 bucket 产生不必要的流量。在其他情况下,你也可以采用不同的配置。详情请参见使用 LIFETIME 刷新字典数据
  1. 现在导入它:
  1. 确认可以查询它:
  1. 很好。现在在查询中使用 dictGet 函数来获取 某个行政区的名称。下面这个查询会汇总终点为 LaGuardia 或 JFK 机场的 各行政区出租车行程数量:
该查询汇总了终点为 LaGuardia 或 JFK 机场的出租车行程,按各 borough 统计数量。请注意,其中有不少行程的 上车区域未知。

执行 JOIN

编写一些查询,将 taxi_zone_dictionarytrips 表进行 JOIN。
  1. 先从一个简单的 JOIN 开始,它的作用与上文机场 查询类似:
请注意,上面的 JOIN 查询输出与上文的 dictGet 查询相同 (只是未包含 Unknown 值) 。在底层, ClickHouse 实际上会对 taxi_zone_dictionary 字典调用 dictGet 函数, 但 JOIN 语法对 SQL 开发者来说更熟悉。
  1. 此查询会返回小费金额最高的 1000 条行程记录, 然后将每一行与该字典执行内连接:
通常,我们会避免在 PostgreSQL 和 ClickHouse 中使用 SELECT *。你 应仅检索实际需要的列。
最后修改于 2026年7月3日