测试DuckDB插件对不同格式xlsx文件的读写效率

我们知道,xlsx是符合OOXML规范的格式,但其实这种格式对其组成部分的容忍度很高。
同一个表格,以不带标题行的3行*3列整数和浮点数据为例。

2659	0.116233238	0.802683908
2734	0.884122563	0.932195575
2745	0.458549115	0.30044512

在duckdb输出的xlsx中的sheet1.xml, 其sheetData标签包裹的部分如下:
如下

<sheetData>
<row r="1">
<c r="A1">
<v>2659</v>
</c>
<c r="B1">
<v>0.1162332380673584</v>
</c>
<c r="C1">
<v>0.8026839081352738</v>
</c>
</row>
<row r="2">
<c r="A2">
<v>2734</v>
</c>
<c r="B2">
<v>0.8841225634634741</v>
</c>
<c r="C2">
<v>0.9321955751461917</v>
</c>
</row>
<row r="3">
<c r="A3">
<v>2745</v>
</c>
<c r="B3">
<v>0.45854911529715814</v>
</c>
<c r="C3">
<v>0.30044511989122274</v>
</c>
</row>
</sheetData>

同一个文件,用wps打开后,再保存为xlsx, 同样的部分变成了

<sheetData>
<row r="1" spans="1:3">
<c r="A1">
<v>2659</v>
</c>
<c r="B1">
<v>0.116233238067358</v>
</c>
<c r="C1">
<v>0.802683908135274</v>
</c>
</row>
<row r="2" spans="1:3">
<c r="A2">
<v>2734</v>
</c>
<c r="B2">
<v>0.884122563463474</v>
</c>
<c r="C2">
<v>0.932195575146192</v>
</c>
</row>
<row r="3" spans="1:3">
<c r="A3">
<v>2745</v>
</c>
<c r="B3">
<v>0.458549115297158</v>
</c>
<c r="C3">
<v>0.300445119891223</v>
</c>
</row>
</sheetData>

比较发现,它给每个row标签增加了spans=“1:3”, duckdb原来生成的文件也能被wps打开,说明这个新增的部分不是必需的。不仅于此,像row和c标签中表示行号列号的r属性,其实也能省略,手工将sheet1.xml这些属性删除,再把它放回xlsx中,文件依然能正常打开,内容完全一致。

<sheetData>
<row>
<c>
<v>2659</v>
</c>
<c>
<v>0.1162332380673584</v>
</c>
<c>
<v>0.8026839081352738</v>
</c>
</row>
<row>
<c>
<v>2734</v>
</c>
<c>
<v>0.8841225634634741</v>
</c>
<c>
<v>0.9321955751461917</v>
</c>
</row>
<row>
<c>
<v>2745</v>
</c>
<c>
<v>0.45854911529715814</v>
</c>
<c>
<v>0.30044511989122274</v>
</c>
</row>
</sheetData>

在文本编辑器,分别选择以上部分,得到大小分别为453、481、372字节,简单数学计算可得,当数据规模扩大时,这个比例大体不变,而部分占整个xml文件的比例会越来越大,因此最终xml文件的大小也差不多这个比例。
下面就实际测试一下4万行256列的随机数据,读取不同标签格式xlsx的用时。

create table t as select i//256 r, i%256 c, random() v from range(10240000)t(i);

create table t40000_256 as pivot t on substr((1000+c)::varchar, -3) using sum(v);

copy t40000_256 to 'duck40000_256.xlsx' with(header 0);

create table duck2 as from 'duck40000_256.xlsx';
Run Time (s): real 5.172 user 4.703125 sys 0.421875
D from duck2 limit 2;
┌────────┬────────────────────┬────────────────────┬───┬─────────────────────┬────────────────────┬────────────────────┐
│   A1   │         B1         │         C1         │ … │         JU1         │        JV1         │        JW1         │
│ double │       double       │       double       │   │       double        │       double       │       double       │
├────────┼────────────────────┼────────────────────┼───┼─────────────────────┼────────────────────┼────────────────────┤
│ 2659.00.11623323806735840.8026839081352738 │ … │    0.355418603349270.65443219295228370.4958646194732272 │
│ 2734.00.88412256346347410.9321955751461917 │ … │ 0.259847207342243870.80552948193144340.1164436018095856 │
├────────┴────────────────────┴────────────────────┴───┴─────────────────────┴────────────────────┴────────────────────┤
│ 2 rows                                                                                         257 columns (6 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.073 user 0.062500 sys 0.000000

再将它用wps保存一次,保存前后的大小

2025/08/20  21:49       130,892,489 duck40000_256.xlsx

2025/08/20  22:01       138,414,845 wps40000_256.xlsx

D create table t3 as from 'wps40000_256.xlsx';

Run Time (s): real 4.136 user 4.062500 sys 0.062500

不可思议,居然多了spans=标签,文件大的wps格式xlsx读取更快,还快了20%。这是excel插件的个例,还是各种读取插件的共性?

再用rusty_sheet插件测试

D load rusty_sheet;

D create table duck3 as from read_sheet('duck40000_256.xlsx',header=0);
Run Time (s): real 8.584 user 8.250000 sys 0.312500

D create table wps3 as from read_sheet('wps40000_256.xlsx',header=0);
Run Time (s): real 8.531 user 8.140625 sys 0.375000

这次两种格式的差距可以忽略不计。
再用spatial插件测试

load spatial;
D create table wps4 as from st_read('wps40000_256.xlsx');
Run Time (s): real 10.561 user 10.359375 sys 0.203125

D create table duck4 as from st_read('duck40000_256.xlsx');
Run Time (s): real 10.746 user 10.828125 sys 0.078125

差距同样可以忽略不计。
再用sheetreader插件测试

load sheetreader;
D create table wps5 as from sheetreader('wps40000_256.xlsx');
Run Time (s): real 1.964 user 4.921875 sys 0.390625
D from wps5 limit 2;
┌──────────┬───────────────────┬───────────────────┬───┬───────────────────┬───────────────────┬───────────────────┐
│ Numeric0 │     Numeric1      │     Numeric2      │ … │    Numeric254     │    Numeric255     │    Numeric256     │
│  doubledoubledouble       │   │      doubledoubledouble       │
├──────────┼───────────────────┼───────────────────┼───┼───────────────────┼───────────────────┼───────────────────┤
│   2659.00.1162332380673580.802683908135274 │ … │  0.355418603349270.6544321929522840.495864619473227 │
│   2734.00.8841225634634740.932195575146192 │ … │ 0.2598472073422440.8055294819314430.116443601809586 │
├──────────┴───────────────────┴───────────────────┴───┴───────────────────┴───────────────────┴───────────────────┤
│ 2 rows                                                                                     257 columns (6 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
D create table duck5 as from sheetreader('duck40000_256.xlsx');
Run Time (s): real 1.679 user 8.046875 sys 0.093750
Invalid Error:
Failed to retrieve shared strings file

奇怪,同样没有sharedstring.xml,wps格式就能读取,而duckdb格式报错,因为duckdb格式xlsx读取失败,没法比较两种格式的读取速度差异。
明天再测一下没有其他标签的速度。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值