怎么理解ClickHouse的向量化执行

这是一个理解 ClickHouse 性能本质的核心问题。如果只用一句话概括:

ClickHouse 的向量化执行,本质是:
不是"一行一行算",而是"一批一批算"。

下面我分 直觉 → 内部机制 → 和行式执行对比 → 为什么快 → 常见误解 五个层次给你讲清楚。


一、先用直觉理解(非常重要)

❌ 传统行式执行(Row-at-a-time)

text 复制代码
for each row:
    取一行
    计算表达式
    判断条件
    输出
  • 每行一次函数调用
  • 分支判断频繁
  • CPU cache 利用率低

✅ ClickHouse 向量化执行(Vectorized)

text 复制代码
for each block (1024 ~ 8192 rows):
    取一整列(数组)
    在数组上做计算
    一次性输出结果列
  • 一次处理一批数据
  • 函数作用于数组(vector)
  • 大量减少 CPU 指令 & 分支

👉 这是 ClickHouse 快的根本原因之一


二、ClickHouse 内部是怎么做的

1️⃣ Block(数据块)

ClickHouse 的最小执行单元不是 row,而是 Block

  • 一个 Block ≈ 一批行
  • 每一列是一个数组(Column
  • 默认 block size:max_block_size(通常 8192)

示意:

text 复制代码
Block:
  user_id   → [u1, u2, u3, ...]
  price     → [10, 20, 30, ...]
  cnt       → [1, 2, 3, ...]

2️⃣ Expression 在列上执行

sql 复制代码
SELECT price * cnt
FROM t
WHERE price > 10

执行逻辑:

  • price > 10

    → 对 price 列数组一次性比较

    → 生成 Bool mask

  • price * cnt

    → 两个数组做逐元素乘法

👉 没有"单行循环"


三、和行式执行的对比(关键)

维度 行式执行 CK 向量化
处理单位 Block(批)
函数调用 每行一次 每列一次
CPU 分支 极少
Cache 命中
SIMD 几乎不可用 可大量使用

四、为什么向量化执行这么快

1️⃣ CPU Cache 友好

  • 连续内存访问
  • 顺序扫描
  • 几乎没有 random access

2️⃣ SIMD 自动加速

现代 CPU 可以:

  • 一条指令处理多个值(AVX2 / AVX-512)

例如:

text 复制代码
price > 10

→ 一条指令比较 8~16 个值


3️⃣ 函数调用 / 分支极少

  • 行式:一行一个 if
  • 向量化:一次判断一整列

五、向量化 ≠ 列存(容易混淆)

概念 含义
列存 数据存储方式
向量化执行 数据处理方式
  • 列存 ≠ 必然向量化
  • 行存 ≠ 不能向量化(但很难)

👉 ClickHouse 是:

列存 + 向量化执行 + 顺序扫描

三者叠加,才有极致性能。


六、ClickHouse 中"哪些地方用到了向量化"

几乎全部核心算子:

  • WHERE 过滤
  • 表达式计算
  • GROUP BY
  • 聚合函数
  • 排序(部分阶段)
  • JOIN(build/probe 阶段)

七、什么时候向量化会"失效"

⚠️ 以下场景会降低向量化优势:

1️⃣ 复杂 UDF / lambda

2️⃣ 每行逻辑分支非常复杂

3️⃣ 极端小数据量(几十行)

4️⃣ 大量 LIKE '%xxx%' / 正则

👉 这时 CPU 成本会上来,但仍比行式好。


八、一个非常重要的工程认知

ClickHouse 的性能不是"索引查得快",
而是"即使扫,也扫得极快"。

向量化执行让"全表扫描"变成了一个可接受、甚至高效的操作。


九、一句话总结(面试级)

ClickHouse 的向量化执行是:
以 Block 为单位,把列当数组,用 SIMD 和顺序内存访问对整批数据做计算,从而极大降低 CPU 指令数和 cache miss。


一、典型场景

  • Flink 实时写入 CK(明细 / 底池 / 选品结果)

  • CK 上:

    • 圈品(等值 + 模糊条件)
    • 统计分析(group by、count、sum)
    • 偶尔 LIKEIN、范围过滤
  • 数据量:百万~十亿级

  • 很关心:

    • 为啥没索引也能跑
    • 为啥 LIKE 不一定慢
    • 为啥扫全表还能接受

👉 这些 全部依赖向量化执行


二、什么 SQL「最能吃满」向量化(你应该多写)

✅ 1️⃣ 等值 / IN / 范围过滤(无索引也不怕)

sql 复制代码
SELECT count(*)
FROM sku_pool
WHERE pool_type = 3
  AND status = 1
  AND price BETWEEN 100 AND 300;

为什么快?

  • pool_type = 3 → 对一整列做批量比较
  • status = 1 → 布尔 mask
  • 没有逐行 if
  • 扫得快 + 算得快

👉 这是 CK 最擅长的形态


✅ 2️⃣ 统计(典型 OLAP)

sql 复制代码
SELECT
    category_id,
    countDistinct(sku_id)
FROM sku_event
WHERE event_date = '2026-01-12'
GROUP BY category_id;

向量化体现在哪?

  • countDistinct 在 block 上批量处理
  • GROUP BY 用哈希表 + 批量 probe
  • cache 命中率极高

👉 这是 CK 的绝对舒适区


✅ 3️⃣ 模糊过滤里的"可控模糊"

sql 复制代码
WHERE title LIKE '耐克%'

比你想象中快的原因:

  • 扫描是列式顺序 IO
  • 前缀匹配在 vector 上跑
  • 比 MySQL 一行一行判断快得多

⚠️ 但注意:
LIKE '%耐克%' 就开始吃 CPU 了(后面说)


三、哪些 SQL 会"拖垮"向量化(你要警惕)

❌ 1️⃣ 大字段 + %LIKE%

sql 复制代码
WHERE json_str LIKE '%"brand":"NIKE"%'

问题在哪?

  • 每行都要做子串扫描
  • 字符串很长
  • SIMD 优势基本丢失

👉 不是 I/O 慢,是 CPU 被吃光


❌ 2️⃣ 复杂 UDF / Lambda

sql 复制代码
WHERE my_custom_func(col1, col2) = 1
  • 每个 block 都要走复杂逻辑
  • 很难 vectorize
  • 退化成"伪行式"

❌ 3️⃣ 极小结果集 + 频繁点查

sql 复制代码
SELECT *
FROM t
WHERE id = 'xxx'
LIMIT 1;
  • CK 能做
  • 但这不是它的强项
  • QPS 高时不如行存数据库

👉 向量化是"批处理友好",不是"点查友好"


四、把「向量化」用在圈品里的正确姿势(很关键)

❌ 错误姿势(行式思维)

"我要一条条 SKU 判断是否符合条件"

✅ 正确姿势(向量化思维)

"我要让每个条件都能在整列上一次性判断"

例如:

sql 复制代码
SELECT sku_id
FROM sku_pool
WHERE
    category_id IN (101,102,103)
    AND price BETWEEN 80 AND 150
    AND brand IN ('NIKE','ADIDAS')
    AND score > 60;
  • 每个条件 → 一次列级判断
  • 最终 mask 合并
  • 输出命中行

👉 这是 CK 天生擅长的圈品方式


五、为什么你会感觉「没索引也不慢」

可以用一句话解释:

CK 的优势不在"跳过多少数据",而在"即使全扫,也用向量化把 CPU 成本压到极低"


六、把这套理解映射回你之前的问题

1️⃣ 为啥 CK 不强调行存?

→ 行存会破坏向量化执行

2️⃣ 为啥 LIKE 和 = 没索引时差别没你想象大?

→ 都在扫,差在 CPU 指令数量

3️⃣ 为啥 CK 适合圈品、分析、不适合 OLTP?

→ 向量化 = 批处理友好


七、一个"工程级"的总结(你可以直接在设计里用)

ClickHouse 的 SQL 设计目标,不是"少扫数据",
而是"让每一次扫描都尽可能线性、连续、向量化"。

当你写 SQL 时,应该问自己一句:

这个条件,是不是能在"列级别"一次性算完?

如果答案是 ,那这条 SQL 基本就稳了。


相关推荐
寻星探路2 小时前
【算法进阶】滑动窗口与前缀和:从“和为 K”到“最小覆盖子串”的极限挑战
java·开发语言·c++·人工智能·python·算法·ai
阿蒙Amon2 小时前
C#每日面试题-简述C#构造函数和析构函数
java·开发语言·c#
gaize12132 小时前
个人建站服务器完全指南:从基础认知到实操选型
运维·服务器
咕噜企业分发小米2 小时前
新人如何利用好云服务器
运维·服务器
musenh2 小时前
spring学习1
java·学习·spring
咕噜企业分发小米2 小时前
如何通过腾讯云防护直播云服务器?
服务器·网络·腾讯云
专注于大数据技术栈2 小时前
java学习--Vector
java·学习
sheji34162 小时前
【开题答辩全过程】以 基于Java的校内美食推荐系统的设计与实现为例,包含答辩的问题和答案
java·开发语言·美食
白典典2 小时前
解决iTextPDF生成手册时目录页码与实际页码不匹配问题
java·spring·intellij-idea