分析型數據庫DuckDB基準測試
我們都知道Polars很快,但是最近DuckDB以其獨特的數據庫特性讓我們對他有了更多的關注,本文將對二者進行基準測試,評估它們的速度、效率和用戶友好性。
在評測之前我們先看看這兩個框架
- DuckDB(0.9.0):一個用c++編寫的內存分析數據庫。
- Polars(0.19.6):一個用Rust實現的超快的DataFrame庫
除此以外還有Pandas、Dask、Spark和Vaex本文主要關注DuckDB和Polars的基準測試,因為它們特別強調在某些環(huán)境下的速度性能。之所以對這兩個框架進行對比是因為 Polars是我目前測試后得到最快的庫,而DuckDB它可以更好的支持SQL,這對于我來說是非常好的特這個,因為我更習慣使用SQL來進行查詢。
指標設置
我使用了官方的polar基準測試存儲庫進行此評估?;鶞蕼y試由tpc標準化查詢組成。這些是專門用來評估實際的、真實的工作流的性能的。在Polars官方網站上,提供了8個此類查詢的詳細結果。這個基準包含22個唯一的查詢(q1、q2等)。這些范圍從多表連接到聚合排序,所有這些都是大家認可的經過特殊構建的查詢。
測試在一臺配備16核AMD vCPU和32GB RAM的機器上進行。所有代碼都使用Python 3.10執(zhí)行。
數據大小
數據是由使用scale10的存儲庫代碼生成的,下面是每個實體的大小
數據轉換與查詢
我們文件讀取到內存中,然后進行查詢。
在q1、q9、q13和q17中,多連接、基于字符串的過濾和復雜聚合的組合對于polars 來說很難像duckdb那樣有效地進行優(yōu)化。Q21是對惟一值的計數、基于這些計數進行過濾以及隨后的一系列連接的操作。
總的來說DuckDB在這兩種情況下看起來更快,但這并不是全部。
因為將數據加載到內存中的過程會產生時間和內存開銷。我們通過Makefile準確地度量這些成本。
/usr/bin/time -v make run_duckdb
/usr/bin/time -v make run_polars
與polar相比,DuckDB在直接讀取文件時表現出更快的性能和更低的內存使用。這表明polars 可能使用了交換內存(紅色)。這些庫不是為跨多臺機器擴展而設計的,所以它們都進行了高效CPU核心利用率的設計。
Polars在某些特定領域表現出具有競爭力甚至更好的性能,例如直接讀取文件時的磁盤IO和內存操作時的RAM IO。在磁盤IOPS較低的系統(tǒng)中,polar可以表現得更好。
另外:上圖中的CPU百分比越高越好。值大于100%表示正在使用多核處理。
下面是我們測試的代碼:
DuckDB讀取Parquet直接查詢
import duckdb
conn = duckdb.connect(database=':memory:')
df_count = conn.sql("""
SELECT
count(*) as count_order
FROM
'lineitem.parquet'
"""
).fetchdf()
print(df_count)
DuckDB內存查詢
import duckdb
conn = duckdb.connect(database=':memory:')
conn.sql("""
CREATE TEMP TABLE IF NOT EXISTS lineitem AS
SELECT *
FROM read_parquet('lineitem.parquet');
"""
)
df_count = conn.sql("""
SELECT
count(*) as count_order
FROM
lineitem
"""
).fetchdf()
print(df_count)
Polars 讀取Parquet直接查詢
import polars as pl
df = pl.scan_parquet('lineitem.parquet')
df_count = df.select(
pl.count().alias("count_order"),
).collect()
print(df_count)
Polars 內存查詢
import polars as pl
df = pl.scan_parquet('lineitem.parquet')
df = df.collect().rechunk().lazy()
df_count = df.select(
pl.count().alias("count_order"),
).collect()
print(df_count)
總結
可以看到在Python處理引擎領域,DuckDB是一個很有前途的競爭者。他在涉及連接和復雜聚合的任務中表現非常亮眼。另外它的簡單并且更干凈、而且還支持SQL語句直接查詢。
但是DuckDB仍處于初級階段。可能偶爾會遇到bug或缺少功能的問題,如果你有興趣,可以在你的研究項目中使用DuckDB替代Polars或者Pandas。
本文的測試腳本:
https://github.com/pola-rs/tpch#polars-tpch