分类
devops

DuckDB vs Polars

DuckDB vs Polars 对比

下面是这两个现代数据处理工具的核心对比:

维度 DuckDB 1.5.4 Polars 1.42.1 赢家
核心接口 SQL(PostgreSQL 风格) Python 表达式 API + 懒加载 DataFrame 看个人偏好
编写语言 C++ Rust —
许可证 MIT MIT —
执行模式 向量化,超内存自动溢出到磁盘 向量化,流式引擎(2026 稳定) 平手
大于 RAM 数据 是(自动溢出) 是(流式引擎) 平手
文件原地读取 Parquet, CSV, JSON, Iceberg, Delta Parquet, CSV, JSON, Iceberg DuckDB 领先
持久化存储 原生 .duckdb + DuckLake 无(仅计算) DuckDB
最佳应用场景 SQL 分析、临时文件查询 Python 数据转换、ETL 管道 —

性能对比

总体印象:在大多数工作负载上,两者的差异比营销宣传的要接近。

具体数据

在 2 TB Parquet 数据集上:
– DuckDB:约 45 秒
– Polars(默认模式):约 60 秒
– Polars(强制异步):约 100 秒

读取 10 GB Parquet 单个文件:
– DuckDB:2–6 秒
– Polars:1.5–5 秒(略胜一筹)

复杂 SQL 查询(500M 行数据):
– DuckDB:8–25 秒
– Polars:10–35 秒(DuckDB 略胜)


记忆使用

在 500M 行数值数据上:
– DuckDB:2–6 GB
– Polars:1.5–5 GB(略微领先)

关键点:内存是真正的分界线。DuckDB 处理超大文件时自动溢出到磁盘,Polars 在流式模式下也能处理超内存数据,但两者各有优劣。


编程范式对比

DuckDB(SQL 优先)

import duckdb

result = duckdb.sql("""
    SELECT customer_id, sum(amount) AS revenue
    FROM 'data/orders/*.parquet'
    GROUP BY customer_id
    ORDER BY revenue DESC
    LIMIT 5
""").show()

Polars(DataFrame 优先)

import polars as pl

result = (
    pl.scan_parquet("data/orders/*.parquet")
      .group_by("customer_id")
      .agg(pl.col("amount").sum().alias("revenue"))
      .sort("revenue", descending=True)
      .limit(5)
      .collect()
)

使用场景推荐

场景 推荐
SQL 分析、BI 仪表板 DuckDB
Python 原生 ETL 管道 Polars
快速文件查询、临时分析 DuckDB
长链式数据转换 Polars
超 TB 级别数据(需自动溢出) DuckDB
需要持久化存储 DuckDB(.duckdb 数据库)

Polars 适合的工作负载

Polars ≈ 本地的、单机的、高性能的 Spark

换个角度:

Pandas → Polars(快 10-100 倍,加上优化器)
         ↓
      Spark(分布式版本,支持超大数据)

✅ 你的数据完全放在一台机器上(即使是 100 GB,现代服务器 RAM 便宜了)
✅ 你需要快速迭代开发(毫秒级反馈)
✅ 本地笔记本 + 云服务器上运行 Python 脚本

# Polars:秒级启动,毫秒级查询
df = pl.read_parquet("sales.parquet")
result = df.filter(pl.col("amount") > 1000).group_by("customer_id").agg(...)
# 立即得到结果