duckdb 比 sqlite 快因默认向量化列式执行、内存批处理、谓词下推与 simd 加速;实操需用 duckdb::connection、appender 批量插入、直接读 parquet,并合理优化 group by 与预编译查询。

duckdb::Connection 为什么比 sqlite3_exec 快那么多
因为 DuckDB 默认启用向量化执行引擎,所有 SQL 操作都在内存中以列式批处理方式运行,跳过了 SQLite 那套逐行解释器 + B-tree 行式扫描的老路。它不依赖磁盘 I/O 做分析,也不需要你手动建索引——列存天然支持谓词下推和 SIMD 加速。
实操建议:
- 用
duckdb::Connection而不是裸 C API(比如duckdb_connect),前者自动管理内存池和查询上下文,避免反复初始化开销 - 批量插入优先走
duckdb::Appender,别用INSERT INTO ... VALUES (...)单条循环,否则会触发大量小事务和 WAL 刷盘 - 如果数据来自 CSV/Parquet,直接用
READ_CSV或SELECT * FROM 'data.parquet',DuckDB 会跳过解析阶段,直接 mmap + 列解码
如何让 GROUP BY + AGG 在千万级数据上不卡住
DuckDB 的聚合默认是单线程 hash-aggregate,但只要加一句 SET threads TO 0;,它就会自动用满 CPU 核心;不过真正影响性能的是分组键的基数和数据局部性。
常见错误现象:GROUP BY 一个高基数 STRING 字段(比如 UUID)时内存暴涨、OOM 或 fallback 到外部排序
实操建议:
- 提前对分组字段做
CAST(... AS VARCHAR(36))或TRIM(),避免隐式类型转换导致哈希冲突升高 - 若分组字段是时间戳,优先转成
DATE或按小时/天切片(date_trunc('day', ts)),降低 key 数量级 - 避免在 GROUP BY 里混用表达式和原始列,例如
GROUP BY user_id, LENGTH(name)会让优化器放弃预聚合路径
duckdb::Prepare() 和直接 Execute() 的性能差别在哪
Prepare 不只是“编译 SQL”,它会做执行计划固化、常量折叠、谓词重写,甚至提前分配向量化 pipeline slot。对于重复执行的 OLAP 查询(比如仪表盘刷新),不 Prepare 就等于每次重解析 + 重优化。
使用场景:定时跑的报表 SQL、用户筛选条件拼接后执行、参数化聚合(如按不同城市统计)
实操建议:
- 用
duckdb::PreparedStatement替代字符串拼接 +Query(),绑定参数用SetParameter(),不是 sprintf - 注意
duckdb::Connection是线程不安全的,每个线程应持有独立 connection,prepare 后的 statement 不能跨 connection 复用 - 如果查询里有子查询或 CTE,Prepare 会缓存中间结果 schema,但不会缓存数据 —— 数据仍按需计算
为什么用 Parquet 作输入源比 CSV 快 5–10 倍
CSV 是纯文本流式解析,每行都要做类型推断、分隔符查找、转义处理;Parquet 是二进制列存格式,DuckDB 可以直接跳到某列某页,跳过无关字段,且内置字典编码和位图过滤。
性能影响:读 1GB CSV 可能吃光 4GB 内存并花 8 秒,同数据 Parquet 通常 1.2 秒 + 800MB 内存
实操建议:
- 入库前用
COPY table_name FROM 'data.csv' (FORMAT 'csv', HEADER true)一次性转成 Parquet 表(CREATE TABLE ... AS SELECT * FROM READ_CSV(...)) - 不要在查询里频繁调用
READ_CSV('x.csv'),尤其带 WHERE 条件时 —— 它无法做列裁剪,整行都得 parse - 如果必须用 CSV,加
sample_size=20000参数帮 DuckDB 更准地猜类型,避免后期 cast 失败重试
最易被忽略的一点:DuckDB 的 OLAP 性能高度依赖数据是否已列式布局。哪怕你用 C++ 把数据全 load 进内存 vector,再用 RegisterFunction 暴露为表,如果不转成 Arrow Table 或 DataFrame,它依然会走慢路径 —— 列式不是靠“快”实现的,是靠“不碰不需要的字节”实现的。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











