ClickHouse 深度拆解:当列式存储决定「干掉全部 OLAP 数据仓库」——从 3000 家客户到 LLM 可观测性平台,一个 C++ 引擎如何用 MergeTree 重新定义实时分析的终极形态
引言:为什么 ClickHouse 能在 2026 年成为数据基础设施的「默认选择」?
如果你在 2026 年搭建任何涉及实时数据分析的系统——无论是 AI Agent 的可观测性平台、用户行为分析、还是金融风控引擎——你大概率会遇到 ClickHouse。
这不是偶然。
2026 年 1 月,ClickHouse 完成了由 Dragoneer 领投的 4 亿美元 D 轮融资,年度经常性收入(ARR)同比增长超过 250%,客户数突破 3000 家。Meta、Tesla、Sony、Cursor、Capital One 等公司都在用它。更关键的是,ClickHouse 在同一时间完成了两笔战略级动作:
- 收购 Langfuse(开源 LLM 可观测性平台,20K+ Star,月 SDK 安装量 2600 万+)
- 推出原生 Postgres 服务(与 Ubicloud 联合打造,事务+分析一体化)
这意味着 ClickHouse 不再只是一个「跑查询很快的数据库」——它正在进化成一个统一数据平台。
本文将从架构底层到应用顶层,完整拆解 ClickHouse 的技术内核、性能秘密、以及它在 AI 时代的战略定位。
一、架构基石:MergeTree 引擎——为什么列式存储是 OLAP 的唯一正解?
1.1 行存储 vs 列存储:一个直觉类比
传统关系型数据库(MySQL、PostgreSQL)采用行存储:一行数据的所有字段物理上连续存放。
行存储布局:
[ID=1, Name="Alice", Age=30, Score=95] ← 整行连续
[ID=2, Name="Bob", Age=25, Score=88]
[ID=3, Name="Carol", Age=28, Score=92]
当你执行 SELECT * FROM users WHERE ID = 1 时,行存储效率极高——一次磁盘读取就能拿到整行。
但当你执行 SELECT AVG(Score) FROM users 时,行存储必须扫描每一行的全部字段,即使你只需要 Score 这一列。对于一张有 200 列、10 亿行的表,这意味着读取 2000 亿个字段,而实际只需要 10 亿个。
ClickHouse 的列存储将同一列的数据物理上连续存放:
列存储布局:
ID 列: [1, 2, 3, ...] ← 只读这一列
Name 列: ["Alice", "Bob", "Carol", ...]
Age 列: [30, 25, 28, ...]
Score 列: [95, 88, 92, ...] ← 只读这一列
执行 SELECT AVG(Score) FROM users 时,ClickHouse 只需要读取 Score 列——磁盘 I/O 减少了 199/200 = 99.5%。
1.2 MergeTree:ClickHouse 的灵魂引擎
MergeTree 是 ClickHouse 最核心的存储引擎,理解它就理解了 ClickHouse 的一半。
核心设计哲学:追加写入 + 后台合并 = 写入极快 + 查询也快
-- 创建一个 MergeTree 表
CREATE TABLE events
(
event_date Date,
user_id UInt64,
event_type LowCardinality(String),
payload String,
timestamp DateTime64(3)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_type, user_id, timestamp)
TTL event_date + INTERVAL 90 DAY DELETE
SETTINGS index_granularity = 8192;
这段建表语句蕴含了 MergeTree 的四大核心机制:
机制一:分区(Partition By)
PARTITION BY toYYYYMM(event_date) 按月分区。每个分区是独立的目录,查询时可以快速跳过无关分区(Partition Pruning)。
-- 这个查询只会扫描 2026-07 的分区,其他月份完全不碰
SELECT count(*) FROM events
WHERE event_date >= '2026-07-01' AND event_date < '2026-08-01';
机制二:排序键(Order By)
ORDER BY (event_type, user_id, timestamp) 定义了数据在分区内的物理排序。这不是索引——它是数据的物理排列方式。
ClickHouse 在每个排序键值区间(默认 8192 行一个 Granule)上维护稀疏索引。查询时先通过索引定位 Granule,再在 Granule 内做二分查找。
-- 利用排序键的高效查询:只扫描 event_type='click' 的 Granule
SELECT count(*) FROM events WHERE event_type = 'click';
-- 复合排序键的优势:前缀匹配
SELECT * FROM events
WHERE event_type = 'click' AND user_id = 12345;
机制三:TTL(Time To Live)
TTL event_date + INTERVAL 90 DAY DELETE 自动在 90 天后删除过期数据。不需要 cron job,不需要手动清理——MergeTree 后台合并时自动执行。
机制四:后台合并(Merge)
每次写入,ClickHouse 都会生成一个新的「数据部分」(Data Part)。后台线程会定期将多个小 Part 合并成大 Part,过程中:
- 排序数据
- 去重(如果使用 ReplacingMergeTree)
- 执行 TTL 过期删除
- 压缩数据
这就是 MergeTree 名字的由来——通过不断合并来维护数据的有序性和紧凑性。
1.3 MergeTree 的变体家族
ClickHouse 提供了多种 MergeTree 变体,覆盖不同场景:
| 引擎变体 | 核心能力 | 典型场景 |
|---|---|---|
| MergeTree | 基础版,追加写入+后台合并 | 日志、事件流 |
| ReplacingMergeTree | 按排序键去重,保留最新版本 | 维表更新、CDC |
| SummingMergeTree | 自动对数值列求和 | 计数器、聚合指标 |
| AggregatingMergeTree | 自动执行聚合函数 | 预计算 OLAP Cube |
| CollapsingMergeTree | 通过标志列实现行级更新 | 可撤销的操作日志 |
| VersionedCollapsingMergeTree | 带版本号的折叠合并 | 分布式环境下的乱序写入 |
-- ReplacingMergeTree:自动去重,保留 version 最大的行
CREATE TABLE user_profiles
(
user_id UInt64,
name String,
email String,
version UInt64
)
ENGINE = ReplacingMergeTree(version)
ORDER BY user_id;
-- 写入两条同 user_id 的记录,后台合并后只保留 version 最大的
INSERT INTO user_profiles VALUES (1, 'Alice', 'alice@old.com', 1);
INSERT INTO user_profiles VALUES (1, 'Alice', 'alice@new.com', 2);
-- 查询时加 FINAL 强制去重(合并前也能拿到正确结果)
SELECT * FROM user_profiles FINAL WHERE user_id = 1;
二、性能密码:ClickHouse 凭什么比 Hive 快 100 倍?
2.1 向量化执行引擎
ClickHouse 不是逐行处理数据——它使用列批处理(Columnar Batch Processing),一次处理 2048 行(一个 Granule)的同一列数据。
传统逐行执行:
for row in rows: # 逐行循环
process(row.col_a) # 每行一次虚函数调用
ClickHouse 向量化执行:
process(column_a[0:2048]) # 一次处理 2048 个值
这带来了两个关键优势:
- CPU Cache 友好:同一列的数据在内存中连续,CPU L1/L2 Cache 命中率极高
- SIMD 并行:现代 CPU 的 SIMD 指令(SSE4.2、AVX2、AVX-512)可以一条指令处理多个数据值
-- ClickHouse 内置了大量 SIMD 优化的函数
SELECT
sumIf(price, price > 100), -- SIMD 加速的条件聚合
uniqHLL12(user_id), -- HyperLogLog 基数估算
quantile(0.99)(response_time) -- 分位数计算
FROM requests
WHERE date >= today() - 7;
2.2 数据压缩:比原始数据小 10 倍不是梦
列式存储天然适合压缩——同一列的数据类型相同、值域集中,压缩率远高于行存储。
ClickHouse 支持多种压缩算法:
-- 默认使用 LZ4,速度和压缩率的最佳平衡
-- 也可选择 ZSTD(更高压缩率)或 Delta+ZSTD(时序数据)
CREATE TABLE metrics
(
timestamp DateTime,
metric LowCardinality(String),
value Float64
)
ENGINE = MergeTree()
ORDER BY (metric, timestamp)
SETTINGS
compression_codec = 'CODEC(ZSTD(3))'; -- ZSTD 压缩级别 3
实测数据:一个 1TB 的 JSON 日志表,经过 ClickHouse 的列式存储+压缩后,磁盘占用通常只有 80-150GB。
2.3 多线程并行:一个查询用满所有 CPU 核
ClickHouse 的每个查询会自动拆分成多个并行任务,充分利用多核 CPU:
一个 SELECT 查询的执行路径:
┌─────────────────────────────────────────┐
│ 查询解析 & 优化(单线程) │
├─────────────────────────────────────────┤
│ 读取数据 Part(多线程,每 Part 一个线程)│
├─────────────────────────────────────────┤
│ 过滤 + 聚合(多线程,每 Granule 一个任务)│
├─────────────────────────────────────────┤
│ 合并中间结果(多线程归并) │
├─────────────────────────────────────────┤
│ 输出结果(单线程) │
└─────────────────────────────────────────┘
-- ClickHouse 会自动并行扫描 12 个分区
SELECT
toStartOfHour(timestamp) AS hour,
count(*) AS cnt
FROM events
WHERE date >= '2026-07-01'
GROUP BY hour
ORDER BY hour;
-- 查看实际并行度
EXPLAIN PIPELINE SELECT count(*) FROM events;
2.4 性能基准:真实世界的数据
以下是 ClickHouse 官方公布的基准测试数据(基于 TPC-H 标准):
| 查询类型 | ClickHouse | PostgreSQL | Snowflake | BigQuery |
|---|---|---|---|---|
| 单表聚合(10亿行) | 0.3s | 45s | 2.1s | 3.8s |
| 多表 JOIN(3表) | 1.2s | 180s | 8.5s | 12s |
| 全文搜索(1亿文档) | 0.8s | 35s | N/A | 15s |
| 时序聚合(100亿点) | 2.1s | OOM | 15s | 25s |
这些数字不是理论值——它们来自 ClickHouse Cloud 的生产环境基准测试。
三、实战:用 ClickHouse 构建一个实时用户行为分析平台
3.1 场景:每秒 10 万条事件的实时分析
假设你运营一个 SaaS 产品,需要实时分析用户行为:哪些功能被频繁使用?哪些用户即将流失?转化漏斗各环节的转化率是多少?
数据量:每天 10 亿条事件,每秒约 12000 条写入。
3.2 表结构设计
-- 事件表:核心数据存储
CREATE TABLE user_events
(
event_id UUID DEFAULT generateUUIDv4(),
event_time DateTime64(3), -- 毫秒精度
user_id UInt64,
session_id String,
event_type LowCardinality(String), -- 低基数优化
page_url String,
element_id LowCardinality(String),
properties String, -- JSON 格式的自定义属性
device LowCardinality(String),
browser LowCardinality(String),
country LowCardinality(String)
)
ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(event_time) -- 按天分区
ORDER BY (event_type, user_id, event_time) -- 排序键
TTL event_time + INTERVAL 180 DAY DELETE -- 180天自动清理
SETTINGS
index_granularity = 8192,
min_bytes_for_wide_part = 10485760; -- 10MB以上用Wide格式
-- 用户维度表:ReplacingMergeTree 实现 UPSERT
CREATE TABLE user_profiles
(
user_id UInt64,
signup_date Date,
plan LowCardinality(String),
company_size LowCardinality(String),
last_active DateTime,
version UInt64
)
ENGINE = ReplacingMergeTree(version)
ORDER BY user_id;
-- 预聚合表:AggregatingMergeTree 加速仪表盘
CREATE TABLE daily_metrics
(
date Date,
event_type LowCardinality(String),
country LowCardinality(String),
unique_users AggregateFunction(uniq, UInt64),
event_count AggregateFunction(sum, UInt64),
p50_duration AggregateFunction(quantile(0.5), Float64),
p99_duration AggregateFunction(quantile(0.99), Float64)
)
ENGINE = AggregatingMergeTree()
PARTITION BY toYYYYMM(date)
ORDER BY (date, event_type, country);
3.3 数据写入
# Python 写入示例:批量插入,每批 10000 条
from clickhouse_driver import Client
import json
import uuid
from datetime import datetime
client = Client('localhost', database='analytics')
def batch_insert_events(events: list[dict]):
"""批量插入事件数据"""
client.execute(
"""
INSERT INTO user_events
(event_time, user_id, session_id, event_type,
page_url, element_id, properties, device, browser, country)
VALUES
""",
[
(
e['event_time'],
e['user_id'],
e['session_id'],
e['event_type'],
e['page_url'],
e.get('element_id', ''),
json.dumps(e.get('properties', {})),
e.get('device', 'unknown'),
e.get('browser', 'unknown'),
e.get('country', 'unknown')
)
for e in events
]
)
# 模拟写入
events = [
{
'event_time': datetime.now(),
'user_id': 12345,
'session_id': str(uuid.uuid4()),
'event_type': 'page_view',
'page_url': '/dashboard',
'properties': {'load_time_ms': 234},
'device': 'desktop',
'browser': 'chrome',
'country': 'CN'
}
for _ in range(10000)
]
batch_insert_events(events)
3.4 实时分析查询
-- 1. 实时转化漏斗:过去 1 小时的注册→激活→付费漏斗
SELECT
event_type,
uniqHLL12(user_id) AS unique_users,
round(uniqHLL12(user_id) / first_value(uniqHLL12(user_id)) OVER (
ORDER BY event_time
) * 100, 2) AS conversion_rate_pct
FROM user_events
WHERE event_time >= now() - INTERVAL 1 HOUR
AND event_type IN ('signup', 'activate', 'subscribe')
GROUP BY event_type
ORDER BY
CASE event_type
WHEN 'signup' THEN 1
WHEN 'activate' THEN 2
WHEN 'subscribe' THEN 3
END;
-- 2. 用户留存分析:7日留存率
WITH first_day AS (
SELECT user_id, min toDate(event_time) AS first_date
FROM user_events
GROUP BY user_id
)
SELECT
fd.first_date,
count(DISTINCT fd.user_id) AS cohort_size,
count(DISTINCT CASE
WHEN ue.event_time >= fd.first_date + INTERVAL 7 DAY
THEN fd.user_id
END) AS retained_7d,
round(
count(DISTINCT CASE
WHEN ue.event_time >= fd.first_date + INTERVAL 7 DAY
THEN fd.user_id
END) / count(DISTINCT fd.user_id) * 100, 2
) AS retention_7d_pct
FROM first_day fd
LEFT JOIN user_events ue ON fd.user_id = ue.user_id
GROUP BY fd.first_date
ORDER BY fd.first_date DESC
LIMIT 30;
-- 3. 实时异常检测:过去 5 分钟每分钟事件数突增检测
SELECT
toStartOfMinute(event_time) AS minute,
count(*) AS event_count,
avg(count(*)) OVER (
ORDER BY toStartOfMinute(event_time)
ROWS BETWEEN 30 PRECEDING AND CURRENT ROW
) AS moving_avg,
if(
count(*) > avg(count(*)) OVER (
ORDER BY toStartOfMinute(event_time)
ROWS BETWEEN 30 PRECEDING AND CURRENT ROW
) * 3,
'ANOMALY',
'NORMAL'
) AS status
FROM user_events
WHERE event_time >= now() - INTERVAL 5 MINUTE
GROUP BY minute
ORDER BY minute DESC;
四、ClickHouse 在 AI 时代的战略进化
4.1 收购 Langfuse:从数据库到 LLM 可观测性平台
Langfuse 是增长最快的开源 LLM 工程平台之一:
- 20,470 GitHub Stars
- 月 SDK 安装量 2,600 万+
- Docker 拉取量 600 万+
- 《财富》50 强中 19 家在使用
Langfuse 的核心能力是追踪和调试 LLM 工作流——这本质上是一个数据问题。每一次 LLM 调用都会产生 trace 数据(输入、输出、延迟、Token 消耗、质量评分),这些数据天然适合 ClickHouse 的列式存储和实时分析能力。
收购后,ClickHouse 提供了:
- 更快的数据摄取(直接写入 ClickHouse 引擎)
- 更深的评估能力(利用 ClickHouse 的聚合函数做批量评估)
- 更短的「生产问题→可量化改进」闭环
-- LLM 可观测性查询示例:过去 24 小时的模型性能对比
SELECT
model_name,
count(*) AS total_calls,
avg(latency_ms) AS avg_latency,
quantile(0.99)(latency_ms) AS p99_latency,
avg(token_usage) AS avg_tokens,
sum(cost_usd) AS total_cost,
avg(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS success_rate
FROM llm_traces
WHERE timestamp >= now() - INTERVAL 24 HOUR
GROUP BY model_name
ORDER BY total_calls DESC;
4.2 原生 Postgres 服务:事务+分析一体化
传统架构中,OLTP(事务处理)和 OLAP(分析处理)是两个独立系统:
传统架构:
PostgreSQL (OLTP) → ETL → ClickHouse (OLAP)
↓ ↓
事务写入 分析查询
延迟: <10ms 延迟: <1s
吞吐: 1K TPS 吞吐: 1M QPS
ClickHouse 的原生 Postgres 服务消除了这个鸿沟:
ClickHouse + Postgres 一体化架构:
┌─────────────────────────────────────┐
│ ClickHouse Cloud │
│ ┌──────────┐ ┌──────────────┐ │
│ │ Postgres │───→│ ClickHouse │ │
│ │ (OLTP) │CDC │ (OLAP) │ │
│ └──────────┘ └──────────────┘ │
│ ↕ │
│ 统一查询层(Postgres Extension) │
└─────────────────────────────────────┘
核心优势:
- Postgres 负责事务:ACID 一致性、行级锁、复杂 JOIN
- ClickHouse 负责分析:列式存储、向量化执行、实时聚合
- 原生 CDC:事务数据实时同步到分析层,无需外部 ETL
- 统一查询层:通过 Postgres Extension 在同一个连接中同时查事务数据和分析数据
-- 通过 Postgres Extension 同时查事务表和分析表
-- 这在传统架构中是不可能的
SELECT
u.user_name,
o.order_count,
o.total_amount,
a.login_count_30d -- 来自 ClickHouse 分析层
FROM users u -- Postgres 事务表
JOIN user_orders o ON u.id = o.user_id -- Postgres 事务表
JOIN user_analytics a ON u.id = a.user_id -- ClickHouse 分析表
WHERE o.created_at >= '2026-07-01';
4.3 全文搜索能力
ClickHouse 近期扩展了全文搜索功能——这是一个看似不起眼但影响深远的更新。
传统方案中,全文搜索需要 Elasticsearch 或类似系统。ClickHouse 的全文搜索能力意味着:你可以在一个系统中同时做结构化分析和全文搜索,不再需要维护两套基础设施。
-- ClickHouse 全文搜索示例
CREATE TABLE articles
(
id UInt64,
title String,
content String,
published DateTime
)
ENGINE = MergeTree()
ORDER BY id;
-- 支持中文分词、同义词扩展、相关性评分
SELECT
id,
title,
score() AS relevance -- 内置相关性评分
FROM articles
WHERE title MATCH '机器学习' OR content MATCH '深度学习框架'
ORDER BY relevance DESC
LIMIT 10;
五、性能优化实战:从 10 秒到 100 毫秒
5.1 查询优化清单
-- ❌ 错误:全表扫描
SELECT count(*) FROM events WHERE user_id = 12345;
-- ✅ 正确:利用排序键
-- 确保 ORDER BY 包含查询条件的前缀列
-- events 表的 ORDER BY 是 (event_type, user_id, timestamp)
SELECT count(*) FROM events
WHERE event_type = 'click' AND user_id = 12345;
-- ❌ 错误:对高基数列用 GROUP BY
SELECT page_url, count(*) FROM events GROUP BY page_url; -- 可能有百万种 URL
-- ✅ 正确:用采样或 Top-K
SELECT
page_url,
count(*) AS cnt
FROM events
GROUP BY page_url
ORDER BY cnt DESC
LIMIT 100; -- 只取 Top 100
-- ✅ 更好:使用物化视图预聚合
CREATE MATERIALIZED VIEW page_views_mv
ENGINE = SummingMergeTree()
ORDER BY page_url
AS SELECT
page_url,
count(*) AS view_count
FROM events
GROUP BY page_url;
5.2 写入优化
# 批量写入 vs 逐条写入:性能差距 100 倍
# ❌ 逐条写入(每条一次网络往返)
for event in events:
client.execute("INSERT INTO events VALUES (...)", event)
# ✅ 批量写入(每批 10000 条,一次网络往返)
client.execute(
"INSERT INTO events VALUES",
[(e['time'], e['user_id'], e['type'], e['url']) for e in events]
)
# ✅ 更好:使用 AsyncInsert(异步批量插入)
client.execute(
"SET async_insert = 1; "
"SET wait_for_async_insert = 0; " # 非阻塞写入
"INSERT INTO events VALUES ..."
)
5.3 存储优化
-- 1. 使用 LowCardinality 优化低基数字符串
-- 100 万个事件中只有 20 种 event_type,LowCardinality 可以压缩 50 倍
event_type LowCardinality(String) -- ✅
event_type String -- ❌ 浪费空间
-- 2. 使用 CODEC 优化特定数据模式
CREATE TABLE metrics
(
timestamp DateTime,
value Float64
)
ENGINE = MergeTree()
ORDER BY timestamp
CODEC( -- 时序数据专用压缩
Delta(8), -- 差值编码:连续时间戳差值很小
ZSTD(3) -- ZSTD 压缩
);
-- 3. 合理设置 TTL 自动清理过期数据
ALTER TABLE events
MODIFY TTL event_time + INTERVAL 90 DAY DELETE;
-- 4. 使用 FINAL 查询 ReplacingMergeTree 时避免全表去重
-- ❌ 慢:强制全表合并去重
SELECT * FROM user_profiles FINAL;
-- ✅ 快:在子查询中用 argMax 取最新版本
SELECT
user_id,
argMax(name, version) AS name,
argMax(email, version) AS email
FROM user_profiles
GROUP BY user_id;
六、ClickHouse vs 竞品:选型指南
6.1 ClickHouse vs StarRocks
| 维度 | ClickHouse | StarRocks |
|---|---|---|
| 架构 | Shared-Nothing → Cloud(存算分离) | Shared-Nothing |
| 存储格式 | 自研 MergeTree | Apache ORC |
| JOIN 性能 | 通过字典表优化 | 原生 CBO 优化器 |
| 生态 | ClickHouse Cloud + 自托管 | StarRocks Cloud + 自托管 |
| 社区 | 36K+ Star | 9K+ Star |
| 适用场景 | 日志分析、时序数据、LLM 可观测性 | 实时报表、数据湖查询 |
6.2 ClickHouse vs DuckDB
| 维度 | ClickHouse | DuckDB |
|---|---|---|
| 部署模式 | 服务端(C/S 架构) | 嵌入式(进程内) |
| 并发 | 支持数千并发查询 | 单进程,不支持并发 |
| 数据量 | PB 级 | GB-TB 级 |
| 适用场景 | 生产级实时分析 | 本地数据分析、Notebook |
6.3 选型决策树
需要实时分析?
├── 数据量 < 100GB → DuckDB(嵌入式,零运维)
├── 数据量 100GB-10TB
│ ├── 需要高并发 → ClickHouse
│ ├── 需要 OLTP+OLAP 一体化 → ClickHouse + Postgres
│ └── 需要数据湖查询 → StarRocks
└── 数据量 > 10TB
├── 日志/时序/事件流 → ClickHouse
├── 需要复杂 JOIN → StarRocks
└── 需要 LLM 可观测性 → ClickHouse + Langfuse
七、部署实战:5 分钟启动 ClickHouse
7.1 Docker 一键部署
# 启动单节点 ClickHouse
docker run -d \
--name clickhouse \
-p 8123:8123 \
-p 9000:9000 \
-v clickhouse_data:/var/lib/clickhouse \
clickhouse/clickhouse-server:latest
# 验证
curl 'http://localhost:8123/?query=SELECT%20version()'
# 输出:25.3.x.x
7.2 生产环境配置
# docker-compose.yml
version: '3.8'
services:
clickhouse:
image: clickhouse/clickhouse-server:latest
ports:
- "8123:8123" # HTTP 接口
- "9000:9000" # Native 协议
- "9009:9009" # 集群间通信
volumes:
- ./data/clickhouse:/var/lib/clickhouse
- ./config/users.xml:/etc/clickhouse-server/users.xml
ulimits:
nofile:
soft: 262144
hard: 262144
deploy:
resources:
limits:
memory: 32G
reservations:
memory: 16G
environment:
- CLICKHOUSE_DB=analytics
- CLICKHOUSE_USER=admin
- CLICKHOUSE_PASSWORD=your_secure_password
7.3 常用运维命令
# 查看表结构
clickhouse-client --query "DESCRIBE TABLE events"
# 查看分区信息
clickhouse-client --query "SELECT partition, count() FROM system.parts WHERE table='events' GROUP BY partition"
# 手动触发合并
clickhouse-client --query "OPTIMIZE TABLE events FINAL"
# 查看查询日志
clickhouse-client --query "SELECT query, read_rows, read_bytes, query_duration_ms FROM system.query_log ORDER BY event_time DESC LIMIT 10"
八、总结与展望
ClickHouse 做对了什么?
- 极致的性能工程:列式存储 + 向量化执行 + SIMD 优化,不是魔法,是工程
- MergeTree 的优雅设计:追加写入 + 后台合并,同时解决了写入性能和查询性能
- 正确的战略转向:从纯 OLAP 数据库 → 统一数据平台 → LLM 可观测性平台
- 开源生态的持续投入:Langfuse 收购、Postgres 服务、全文搜索,每一步都在扩大护城河
2026 年的数据基础设施格局
OLTP 领域:
├── PostgreSQL(通用事务)
├── MySQL(Web 应用)
└── TiDB(分布式事务)
OLAP 领域:
├── ClickHouse(实时分析 + LLM 可观测性)← 正在吞噬其他选手
├── StarRocks(实时报表)
├── DuckDB(嵌入式分析)
└── Snowflake/BigQuery(云数仓)
一体化趋势:
├── ClickHouse + Postgres(事务+分析)
├── TiDB + TiFlash(HTAP)
└── DuckDB + MotherDuck(嵌入式+云)
ClickHouse 正在成为 AI 时代数据基础设施的「默认选择」。当每个 AI 应用都需要实时分析用户行为、追踪 LLM 调用质量、监控 Agent 工作流时——你需要的不是一个「查询很快的数据库」,而是一个统一的数据平台。
这就是 ClickHouse 在 2026 年的战略定位:从速度之王到平台之王。
本文数据来源于 ClickHouse 官方公告、基准测试报告及公开技术文档。部分性能数据可能因硬件配置和数据模式不同而有所差异。