分析型数据库DuckDB基准测试

本文对比了DuckDB和Polars在速度、效率方面的性能,特别关注SQL支持和内存优化。DuckDB在连接和复杂聚合任务中表现出色,但Polars在某些场景下内存使用更有效率。
摘要由CSDN通过智能技术生成

3f98af7de4305a23ccd8199fdc06d755.png

来源:DeepHub IMBA
本文约1300字,建议阅读5分钟
我们都知道Polars很快,但是最近DuckDB以其独特的数据库特性让我们对他有了更多的关注,本文将对二者进行基准测试,评估它们的速度、效率和用户友好性。

97bcfbb283d1e7bf16f9a348415a48c6.png

在评测之前我们先看看这两个框架

DuckDB(0.9.0):一个用c++编写的内存分析数据库。

Polars(0.19.6):一个用Rust实现的超快的DataFrame库

除此以外还有Pandas、Dask、Spark和Vaex本文主要关注DuckDB和Polars的基准测试,因为它们特别强调在某些环境下的速度性能。之所以对这两个框架进行对比是因为 Polars是我目前测试后得到最快的库,而DuckDB它可以更好的支持SQL,这对于我来说是非常好的特这个,因为我更习惯使用SQL来进行查询。

指标设置

我使用了官方的polar基准测试存储库进行此评估。基准测试由tpc标准化查询组成。这些是专门用来评估实际的、真实的工作流的性能的。在Polars官方网站上,提供了8个此类查询的详细结果。这个基准包含22个唯一的查询(q1、q2等)。这些范围从多表连接到聚合排序,所有这些都是大家认可的经过特殊构建的查询。

测试在一台配备16核AMD vCPU和32GB RAM的机器上进行。所有代码都使用Python 3.10执行。

数据大小

数据是由使用scale10的存储库代码生成的,下面是每个实体的大小

02f8df3648a631e7aa3acba89889ff6a.png


数据转换与查询

我们文件读取到内存中,然后进行查询。

d90a51deb01f143d24737296b2d5d4f7.png

在q1、q9、q13和q17中,多连接、基于字符串的过滤和复杂聚合的组合对于polars 来说很难像duckdb那样有效地进行优化。Q21是对惟一值的计数、基于这些计数进行过滤以及随后的一系列连接的操作。

总的来说DuckDB在这两种情况下看起来更快,但这并不是全部。

因为将数据加载到内存中的过程会产生时间和内存开销。我们通过Makefile准确地度量这些成本。

/usr/bin/time -v make run_duckdb
 /usr/bin/time -v make run_polars

1c098c3df7e3a5b730e5c02ec26169d4.png

与polar相比,DuckDB在直接读取文件时表现出更快的性能和更低的内存使用。这表明polars 可能使用了交换内存(红色)。这些库不是为跨多台机器扩展而设计的,所以它们都进行了高效CPU核心利用率的设计。

Polars在某些特定领域表现出具有竞争力甚至更好的性能,例如直接读取文件时的磁盘IO和内存操作时的RAM IO。在磁盘IOPS较低的系统中,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

编辑:文婧

394f60ca5ee3f88792d99cd4d2a0c2e8.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
金仓分析数据库(KingbaseES)是一款高性能、高可靠性的企业级数据库系统,以下是金仓分析数据库的安装教程: 1. 下载安装包:您可以从金仓官方网站或官方渠道获取适用于您操作系统版本的金仓分析数据库安装包。 2. 解压安装包:使用解压工具(如tar命令)将下载的安装包解压到您选择的安装目录中。 3. 进入安装目录:使用终端或命令行工具进入解压后的安装目录。 4. 执行安装脚本:运行安装脚本进行数据库系统的安装。根据操作系统的不同,安装脚本可能有所差异。一般情况下,您可以通过以下命令来执行安装脚本: ``` ./install.sh ``` 5. 配置数据库参数:根据您的需求和系统配置,进行数据库参数的配置。这些参数包括数据库存储路径、端口号、内存大小等。您可以编辑数据库的配置文件来修改这些参数。 6. 初始化数据库:运行初始化脚本来创建数据库实例和系统表空间。一般情况下,您可以使用以下命令完成初始化: ``` ./initdb.sh ``` 7. 启动数据库服务:通过启动脚本启动金仓分析数据库服务。一般情况下,您可以使用以下命令来启动数据库服务: ``` ./startdb.sh ``` 8. 验证数据库状态:使用命令行工具或金仓提供的客户端工具连接到数据库,验证数据库的状态是否正常运行。 以上是金仓分析数据库的基本安装流程。请注意,具体的安装步骤可能因版本和操作系统而有所差异。建议您查阅官方文档或联系金仓官方支持获取更详细的安装指南和相关帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值