【Rust 2026教程:从零构建 Mini-OLAP 引擎】第 6 章 Benchmark 与优化路线图

1.1 背景知识

写完一个引擎远远不是终点。OLAP 的工程深水区在于优化------同样一份代码,常数项的差异可以达到 10 倍以上。

我们用 TPC-H 的简化负载评估 MiniDuck,对照 DuckDB CLI。

1.2 Benchmark 结果

数据:自造 lineitem 风格表,1000 万行,约 200MB。

查询 DuckDB 1.x MiniDuck v1 比值
SELECT COUNT(*) FROM t WHERE amount > 50 0.04 s 0.18 s 22%
SELECT city_id, SUM(amount) FROM t GROUP BY city_id 0.12 s 0.31 s 39%
SELECT city_id, AVG(amount * 1.13) FROM t WHERE flag = 1 GROUP BY city_id 0.18 s 0.55 s 33%

教学版本能稳定到 DuckDB 的 30%~40%,已经远好于 SQLite/Pandas。差距主要来自下面这些"魔鬼细节"。

1.3 优化路线图

Tier 1:低成本高收益(建议读者动手)

  1. 列裁剪:Scan 阶段只读 SQL 涉及的列,不读其他列
  2. 谓词下推Filter 推到 Scan 内,扫描时直接生成 selection vector
  3. Arc<Table> :消除 clone(仓库已实现)
  4. 复用 batch buffer :避免每次分配新 Vec
  5. #[inline] + target-cpu=native:直接用上 AVX2/AVX-512

Tier 2:进阶(需要重构)

  1. Selection vector 模型 :所有算子接受 (batch, sel: &[u32]),避免反复物理拷贝
  2. 类型特化 :对 i32/i64/f32/f64 分别 monomorphize 算子,去掉 dyn 调度
  3. 多 key hash agg:用 row-format 序列化多列 key
  4. Parallel scan:用 Rayon 把 batch 分发到多线程

Tier 3:研究级

  1. Morsel-driven parallelism(HyPer 论文):动态 work-stealing 替代静态划分
  2. Adaptive execution:运行时切换 hash agg / sort agg
  3. JIT 编译 表达式:Cranelift 把热点表达式编成机器码
  4. Push-based execution(DuckDB 已切换):算子之间反向"推"数据

1.4 总结

我们用大约 400 行 Rust(含三方库胶水),实现了一个具备以下能力的 OLAP 引擎:

  • 列式存储(Arrow 兼容) - 向量化执行 - 表达式解释器 - 哈希聚合 - SQL 解析与计划 - 性能达 DuckDB 的 30%~40%

这套架构与 DuckDB、DataFusion、ClickHouse 的内核思路一致,量级有别------理解了 MiniDuck,再去读这些工业级引擎的源码会顺畅得多。

1.5 终极自测

  1. 你能徒手画出 MiniDuck 从 SQL 字符串到结果输出的完整数据流吗?标出每一步的输入/输出类型
  2. 如果让你给 MiniDuck 加 JOIN,你会优先实现 Hash Join 还是 Merge Join?为什么?
  3. 列出至少 5 个 MiniDuck 与生产级 OLAP 引擎的差距
  4. 如果要把 MiniDuck 改造成"分布式",最先遇到的瓶颈是什么?参考 Presto、ClickHouse、Snowflake 的不同选择

1.6 拓展学习

  • DuckDB 团队博客 duckdb.org/news,每篇文章都是一个优化点深挖
  • DataFusion 是用 Rust 写的"工业级版 MiniDuck",强烈建议作为下一站
  • 论文:Photon: A Fast Query Engine for Lakehouse Systems(Databricks,SIGMOD 2022)
  • 视频:CMU 15-721 Advanced Database Systems,全网最系统的 OLAP 内核课程

配套仓库使用

下载并解压 miniduck.zip

bash 复制代码
unzip miniduck.zip && cd miniduck
cargo build                    # 编译
cargo test                     # 集成测试 4/4
cargo run --example ch1_table  # 第 1 章 demo
cargo run --example ch2_scan   # 第 2 章 demo
cargo run --example ch3_filter # 第 3 章 demo
cargo run --example ch4_agg    # 第 4 章 demo
cargo run --example ch5_sql    # 第 5 章 端到端 SQL
cargo bench                    # 第 6 章 benchmark

仓库结构:

python 复制代码
miniduck/
├── Cargo.toml
├── README.md
├── src/
│   ├── lib.rs
│   ├── storage.rs        # Ch1
│   ├── exec.rs           # Ch2
│   ├── expr.rs           # Ch3
│   ├── agg.rs            # Ch4
│   ├── catalog.rs        # Ch5
│   └── planner.rs        # Ch5
├── examples/
│   ├── ch1_table.rs
│   ├── ch2_scan.rs
│   ├── ch3_filter.rs
│   ├── ch4_agg.rs
│   └── ch5_sql.rs
├── benches/
│   └── tpch_lite.rs      # Ch6
└── tests/
    └── integration.rs

Happy hacking! 完成本教程后,下一步建议直接阅读 DataFusion 源码------它就是这套架构的工业级实现,1.5 万星 Rust 项目。

相关推荐
Rust语言中文社区1 小时前
【Rust日报】2026-05-14 Pyrefly v1.0 正式发布:快速的 Python 类型检查器和语言服务器
开发语言·后端·python·rust
GreenTea2 小时前
【Rust 2026教程:从零构建 Mini-OLAP 引擎】第 5 章 SQL → 逻辑计划 → 物理计划
后端
GreenTea2 小时前
【Rust 2026教程:从零构建 Mini-OLAP 引擎】第 4 章 哈希聚合:GROUP BY 的核心
后端
IT_陈寒2 小时前
Vue的v-for为什么不加key也能工作?我差点翻车
前端·人工智能·后端
GreenTea2 小时前
【Rust 2026教程:从零构建 Mini-OLAP 引擎】第 3 章 表达式系统:把 SQL 表达式变成可执行树
后端
GreenTea2 小时前
【Rust 2026教程:从零构建 Mini-OLAP 引擎】第 2 章 向量化执行:让 CPU 跑满
后端
GreenTea2 小时前
【Rust 2026教程:从零构建 Mini-OLAP 引擎】第 1 章 列式存储:OLAP 的物理基石
后端
rocky_rocky3 小时前
ComboBox的异步延迟加载机制
后端
接着奏乐接着舞3 小时前
spring cloud知识点
后端·spring·spring cloud