Skip to content

DuckDB百亿级数据性能测试

前面有说过,DuckDB的创建者一开始就放弃了分布式,然后就有同学提出质疑,DuckDB会有性能瓶颈。我只想说,目前DuckDB可以说是单机场景下大数据量分析的最佳选择。

本文,我将为同学们演示DuckDB在百亿级数据量下的性能表现,我感觉我已经彻底魔怔了,百亿级数据量意味着什么?

百亿级数据是多少

我们假设一家企业每天可以产生1000万的数据量,那么产生100亿的数据量就需要1000天(超过两年半)。

我们按照前文3亿数据量,CSV文件约9GB,那么100亿就是300G。这个数据量我相信这个世界上已经没有几个单机可以处理这个CSV文件了。

此情此景,如何解决呢?

答案就是Parquet。

Parquet是什么

Parquet又称Apache Parquet,是Apache Hadoop生态系统的一种免费、开源的面向列的数据存储格式。

Parquet优点

  • 数据压缩

  • 列式存储

  • 与编程语言无关

  • 开源格式,免费使用

  • 支持复杂数据类型

创建超百亿的数据量

  1. 创建数据库文件并创建表
sql
CREATE TABLE weather (
    city    VARCHAR,
    temp_lo INTEGER,
    temp_hi INTEGER,
    prcp    REAL,
    date    DATE
);

  1. 插入数据
sql
INSERT INTO main.weather
VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');

  1. 反复插入数据,使单表数据量达到上亿级别
sql
INSERT INTO main.weather
select * from main.weather;

重复执行SQL,单表数据量会达到上40亿级别。

数据量超40亿之后再使用该方式可能会提示内存不足,所以我们再优化一下

sql
INSERT INTO main.weather
select * from main.weather limit 500000000;

每次我们只插入5亿条数据,重复插入,知道达到超过100亿。

  1. 确认单表数据量
sql
select count(*) from main.weather;

这边百亿只超过了1条,调皮一下下。

  1. 测试内部表查询性能
sql
select city, count(*), sum(temp_lo), sum(temp_hi) from main.weather
group by city;

耗时约34s,你是否能接受呢。

  1. 导出为Parquet格式
sql
copy main.weather to 'E:\duckdbtest\weather.parquet' (format 'parquet');

由于导出时间过长,则先导出1亿数据量,然后通过复制的方式得到100份含有一亿数据量的文件。

sql
copy (select * from main.weather limit 100000000) to 'E:\duckdbtest\weather.parquet' (format 'parquet');

  1. 验证数据量
sql
select count(*) from 'E:\duckdbtest\*.parquet';

通过正则匹配的方式,可以把多个文件里的数据合并读取,这也是DuckDB更灵活的特点。

分组聚合

sql
select city, sum(temp_lo), sum(temp_hi) from 'E:\duckdbtest\*.parquet'
group by city;

耗时约4min。

总结,Parquet相比CSV可以节省大量的存储空间,查询性能也更好,100亿数据量4min内完成聚合计算,表现还是相当可以的。但是性能最好的还是DuckDB的内部表,可以把数据读出数据后保存到内部表后再做分析。

sql
create table weater_parquet as
select * from 'E:\duckdbtest\*.parquet';

如果一次写入太慢,可以考虑分批写入。

进阶

在日常处理数据过程中,对于中间数据过程可以尝试使用占用空间更少的Parquet格式,同时Parquet文件也可以用于Hive等其它大数据产品中。针对复杂的分析需求,可以使用数仓开发的分层思维,一层层做聚合,使得开发效果达到最高。想要学习DuckDB更多玩法,请关注:遇码,回复duckdb,获取官方文档。

遇码MeetCoding 开源技术社区