除了创作者张先生本人,我可能是全网第二个用到的人,倍感荣幸,8月9日,先用了第一版,还有一些问题,比如读入百万行的表格出错,经过他两天的改进,无论从功能还是性能都全面超越官方excel插件的读取。
直接上对比吧, 测试环境wsl ubuntu 22.04
DuckDB v1.3.2 (Ossivalis) 0b83e5d2f6
Enter ".help" for usage hints.
D load rusty_sheet;
D from read_sheet('foods.xlsx')limit 4;
┌────────────┬──────────┬────────┬──────────┐
│ category │ calories │ fats_g │ sugars_g │
│ varchar │ int64 │ double │ int64 │
├────────────┼──────────┼────────┼──────────┤
│ vegetables │ 45 │ 0.5 │ 2 │
│ 海鲜 │ 150 │ 5.0 │ 0 │
│ 肉 │ 100 │ 5.0 │ 0 │
│ fruit │ 60 │ 0.0 │ 11 │
└────────────┴──────────┴────────┴──────────┘
D .timer on
D SET enable_progress_bar =false;
Run Time (s): real 0.002 user 0.000612 sys 0.001426
D from read_sheet('exli2.xlsx');
┌────────────┬───────────┬───────────┬──────────────┬───┬───────────────────┬────────────┬──────────────────────┐
│ l_orderkey │ l_partkey │ l_suppkey │ l_linenumber │ … │ l_shipinstruct │ l_shipmode │ l_comment │
│ int64 │ int64 │ int64 │ int64 │ │ varchar │ varchar │ varchar │
├────────────┼───────────┼───────────┼──────────────┼───┼───────────────────┼────────────┼──────────────────────┤
│ 1 │ 155190 │ 7706 │ 1 │ … │ DELIVER IN PERSON │ TRUCK │ to beans x-ray car… │
...
│ 1048483 │ 50070 │ 2576 │ 4 │ … │ DELIVER IN PERSON │ REG AIR │ regularly expre │
├────────────┴───────────┴───────────┴──────────────┴───┴───────────────────┴────────────┴──────────────────────┤
│ 1048575 rows (40 shown) 16 columns (7 shown) │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 19.667 user 14.900739 sys 1.462614
D install excel;
D load excel;
D from read_xlsx('exli2.xlsx');
┌────────────┬───────────┬───────────┬──────────────┬───┬───────────────────┬────────────┬──────────────────────┐
│ l_orderkey │ l_partkey │ l_suppkey │ l_linenumber │ … │ l_shipinstruct │ l_shipmode │ l_comment │
│ double │ double │ double │ double │ │ varchar │ varchar │ varchar │
├────────────┼───────────┼───────────┼──────────────┼───┼───────────────────┼────────────┼──────────────────────┤
│ 1.0 │ 155190.0 │ 7706.0 │ 1.0 │ … │ DELIVER IN PERSON │ TRUCK │ to beans x-ray car… │
...
│ 1048483.0 │ 50070.0 │ 2576.0 │ 4.0 │ … │ DELIVER IN PERSON │ REG AIR │ regularly expre │
├────────────┴───────────┴───────────┴──────────────┴───┴───────────────────┴────────────┴──────────────────────┤
│ 1048575 rows (40 shown) 16 columns (7 shown) │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 26.600 user 6.434064 sys 1.568509
D from read_xlsx('pysale20.xlsx');
┌─────────┬─────────────────────┬─────────┬────────┬────────┬───┬────────┬────────┬────────┬────────┬────────┬────────┐
│ s_name │ s_date │ good_id │ v1 │ v2 │ … │ v15 │ v16 │ v17 │ v18 │ v19 │ v20 │
│ varchar │ timestamp │ double │ double │ double │ │ double │ double │ double │ double │ double │ double │
├─────────┼─────────────────────┼─────────┼────────┼────────┼───┼────────┼────────┼────────┼────────┼────────┼────────┤
│ sale0 │ 2020-10-10 00:00:00 │ 0.0 │ 0.0 │ 0.0 │ … │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │
...
│ sale19 │ 2020-10-29 00:00:00 │ 19.0 │ 1.9 │ 3.8 │ … │ 28.5 │ 30.4 │ 32.3 │ 34.2 │ 36.1 │ 38.0 │
├─────────┴─────────────────────┴─────────┴────────┴────────┴───┴────────┴────────┴────────┴────────┴────────┴────────┤
│ 20 rows 23 columns (11 shown) │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.050 user 0.006675 sys 0.000865
D from read_sheet('pysale20.xlsx');
┌─────────┬────────────┬─────────┬────────┬────────┬────────┬───┬────────┬────────┬────────┬────────┬────────┬───────┐
│ s_name │ s_date │ good_id │ v1 │ v2 │ v3 │ … │ v15 │ v16 │ v17 │ v18 │ v19 │ v20 │
│ varchar │ date │ int64 │ double │ double │ double │ │ double │ double │ double │ double │ double │ int64 │
├─────────┼────────────┼─────────┼────────┼────────┼────────┼───┼────────┼────────┼────────┼────────┼────────┼───────┤
│ sale0 │ 2020-10-10 │ 0 │ 0.0 │ 0.0 │ 0.0 │ … │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0 │
...
│ sale19 │ 2020-10-29 │ 19 │ 1.9 │ 3.8 │ 5.7 │ … │ 28.5 │ 30.4 │ 32.3 │ 34.2 │ 36.1 │ 38 │
├─────────┴────────────┴─────────┴────────┴────────┴────────┴───┴────────┴────────┴────────┴────────┴────────┴───────┤
│ 20 rows 23 columns (12 shown) │
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.010 user 0.003372 sys 0.000000
D copy (from '5m Sales Records.csv') to '5msale.xlsx';
Run Time (s): real 11.580 user 22.658606 sys 0.100720
Invalid Input Error:
XLSX: Sheet row limit of '1048576' rows exceeded!
* XLSX files and compatible applications generally have a limit of '1048576' rows
* You can export larger sheets at your own risk by setting the 'sheet_row_limit' parameter to a higher value
D copy (from '5m Sales Records.csv') to '5msale.xlsx' WITH (FORMAT xlsx, HEADER true,sheet_row_limit 10485760);
Run Time (s): real 56.152 user 50.550407 sys 0.250691
D from '5msale.xlsx' limit 3;
┌──────────────────────┬─────────┬─────────────────┬───────────────┬───┬───────────────┬────────────┬──────────────┐
│ Region │ Country │ Item Type │ Sales Channel │ … │ Total Revenue │ Total Cost │ Total Profit │
│ varchar │ varchar │ varchar │ varchar │ │ double │ double │ double │
├──────────────────────┼─────────┼─────────────────┼───────────────┼───┼───────────────┼────────────┼──────────────┤
│ Australia and Ocea… │ Palau │ Office Supplies │ Online │ … │ 1563555.21 │ 1260428.96 │ 303126.25 │
│ Europe │ Poland │ Beverages │ Online │ … │ 443183.0 │ 296918.6 │ 146264.4 │
│ North America │ Canada │ Cereal │ Online │ … │ 21187.1 │ 12062.33 │ 9124.77 │
├──────────────────────┴─────────┴─────────────────┴───────────────┴───┴───────────────┴────────────┴──────────────┤
│ 3 rows 14 columns (7 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 102.152 user 2.747445 sys 5.665771
D from read_sheet('5msale.xlsx') limit 3;
┌──────────────────────┬─────────┬─────────────────┬───────────────┬───┬───────────────┬────────────┬──────────────┐
│ Region │ Country │ Item Type │ Sales Channel │ … │ Total Revenue │ Total Cost │ Total Profit │
│ varchar │ varchar │ varchar │ varchar │ │ double │ double │ double │
├──────────────────────┼─────────┼─────────────────┼───────────────┼───┼───────────────┼────────────┼──────────────┤
│ Australia and Ocea… │ Palau │ Office Supplies │ Online │ … │ 1563555.21 │ 1260428.96 │ 303126.25 │
│ Europe │ Poland │ Beverages │ Online │ … │ 443183.0 │ 296918.6 │ 146264.4 │
│ North America │ Canada │ Cereal │ Online │ … │ 21187.1 │ 12062.33 │ 9124.77 │
├──────────────────────┴─────────┴─────────────────┴───────────────┴───┴───────────────┴────────────┴──────────────┤
│ 3 rows 14 columns (7 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 87.944 user 68.935756 sys 6.922954
D from read_sheet('foo*.xlsx') limit 3;
Run Time (s): real 0.076 user 0.009866 sys 0.020250
Binder Error:
Read spreadsheet failed: Invalid xlsx file format: I/O error: No such file or directory (os error 2)
D from read_sheet('test/datebool_test.xlsx') limit 3;
Run Time (s): real 0.075 user 0.000000 sys 0.054503
Binder Error:
table "read_sheet" has duplicate column name "1993-10-21"
D from read_sheet('test/datebool_test.xlsx' ,header=false) limit 3;
┌────────────┬────────────┬─────────┐
│ column1 │ column2 │ column3 │
│ date │ date │ boolean │
├────────────┼────────────┼─────────┤
│ 1993-10-21 │ 1993-10-21 │ true │
│ 1994-09-25 │ 1994-09-25 │ false │
│ 2024-05-24 │ 2024-05-24 │ true │
└────────────┴────────────┴─────────┘
Run Time (s): real 0.027 user 0.008031 sys 0.014112
D from read_sheet('test/numeric_test.xlsx' ,header=false) limit 3;
┌─────────┬──────────────┬──────────────┬───────────┬───────────┬───────────┐
│ column1 │ column2 │ column3 │ column4 │ column5 │ column6 │
│ double │ double │ double │ double │ double │ double │
├─────────┼──────────────┼──────────────┼───────────┼───────────┼───────────┤
│ 5.0 │ 5.0 │ 5.0 │ 5.0 │ 5.0 │ 5.0 │
│ -5.0 │ -5.0 │ -5.0 │ -5.0 │ -5.0 │ -5.0 │
│ 42767.0 │ 3147483647.0 │ 3147483647.0 │ 5.1234567 │ 5.1234567 │ 5.1234567 │
└─────────┴──────────────┴──────────────┴───────────┴───────────┴───────────┘
Run Time (s): real 0.028 user 0.011808 sys 0.000108
D from read_sheet('test/string_test.xlsx' ,header=false) limit 3;
┌─────────┬──────────┬─────────┐
│ column1 │ column2 │ column3 │
│ varchar │ varchar │ varchar │
├─────────┼──────────┼─────────┤
│ Dies │ beiden │ Zeilen │
│ sollten │ geskippt │ werden │
│ Meine │ Test │ Daten │
└─────────┴──────────┴─────────┘
Run Time (s): real 0.024 user 0.004291 sys 0.002822
D from read_sheet('test/sf0001/nation.xlsx' ,header=false) limit 3;
┌─────────┬───────────┬─────────┬──────────────────────────────────────────────────────────────────────────────────────┐
│ column1 │ column2 │ column3 │ column4 │
│ int64 │ varchar │ int64 │ varchar │
├─────────┼───────────┼─────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ 0 │ ALGERIA │ 0 │ haggle. carefully final deposits detect slyly agai │
│ 1 │ ARGENTINA │ 1 │ al foxes promise slyly according to the regular accounts. bold requests alon │
│ 2 │ BRAZIL │ 1 │ y alongside of the pending deposits. carefully special packages are about the iron… │
└─────────┴───────────┴─────────┴──────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.025 user 0.004716 sys 0.000453
D from read_sheet('test/sf0001/lineitem.xlsx' ,header=false) limit 3;
┌─────────┬─────────┬─────────┬─────────┬───┬────────────┬───────────────────┬──────────┬──────────────────────┐
│ column1 │ column2 │ column3 │ column4 │ … │ column13 │ column14 │ column15 │ column16 │
│ int64 │ int64 │ int64 │ int64 │ │ date │ varchar │ varchar │ varchar │
├─────────┼─────────┼─────────┼─────────┼───┼────────────┼───────────────────┼──────────┼──────────────────────┤
│ 1 │ 156 │ 4 │ 1 │ … │ 1996-03-22 │ DELIVER IN PERSON │ TRUCK │ egular courts abov… │
│ 1 │ 68 │ 9 │ 2 │ … │ 1996-04-20 │ TAKE BACK RETURN │ MAIL │ ly final dependenc… │
│ 1 │ 64 │ 5 │ 3 │ … │ 1996-01-31 │ TAKE BACK RETURN │ REG AIR │ riously. regular, … │
├─────────┴─────────┴─────────┴─────────┴───┴────────────┴───────────────────┴──────────┴──────────────────────┤
│ 3 rows 16 columns (8 shown) │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 0.121 user 0.044454 sys 0.051056
D copy (from 'NYC_311_SR_2010-2020-sample-1M.csv') to 'NYC1M.xlsx';
D .timer on
D from read_sheet('NYC1M.xlsx') limit 3;
Run Time (s): real 26.009 user 19.407039 sys 1.951871
Binder Error:
Read spreadsheet failed: Missing column name at row=0 column=13
D from read_xlsx('NYC1M.xlsx') limit 3;
Run Time (s): real 53.642 user 30.268892 sys 2.736369
Invalid Input Error:
read_xlsx: Failed to parse cell 'N3': Could not convert string 'WILLOUGHBY AVENUE' to DOUBLE
D from read_xlsx('NYC1M.xlsx',header=0) limit 3;
Run Time (s): real 54.498 user 1.903058 sys 2.505033
Invalid Input Error:
read_xlsx: Failed to parse cell 'N3': Could not convert string 'WILLOUGHBY AVENUE' to DOUBLE
D from read_sheet('NYC1M.xlsx',header=false) limit 3;
┌──────────┬─────────────────────┬───┬───────────────────┬────────────────────┬──────────────────────┐
│ column1 │ column2 │ … │ column39 │ column40 │ column41 │
│ int64 │ timestamp │ │ double │ double │ varchar │
├──────────┼─────────────────────┼───┼───────────────────┼────────────────────┼──────────────────────┤
│ 42254749 │ 2019-04-18 21:55:45 │ … │ 40.5863974 │ -73.9325913 │ (40.5863974, -73.9… │
│ 16561258 │ 2010-05-01 09:59:44 │ … │ 40.7672147 │ -73.9880831 │ (40.7672147, -73.9… │
│ 46412656 │ 2020-05-21 18:15:38 │ … │ 40.69113738107441 │ -73.95955540938948 │ (40.69113738107441… │
├──────────┴─────────────────────┴───┴───────────────────┴────────────────────┴──────────────────────┤
│ 3 rows 41 columns (5 shown) │
└────────────────────────────────────────────────────────────────────────────────────────────────────┘
Run Time (s): real 25.872 user 19.902876 sys 1.700847
D .exit
root@DESKTOP-59T6U68:/mnt/c/d# time /mnt/c/d/calamine/target/release/examples/excel_to_csv /mnt/c/d/5msale.xlsx Sheet1
real 1m2.165s
user 0m36.777s
sys 0m4.680s
就算与calamine自带的例子比,慢得也不多,毕竟读取之后还要全量做类型转换,多了很多工作量,再算上经过DuckDB一道的开销,这种时间损耗的确不算什么。
附录:
测试数据集
1 500万销售员 https://excelbianalytics.com/wp/wp-content/uploads/2020/09/5m-Sales-Records.7z
2 100万出租车 https://raw.githubusercontent.com/wiki/jqnatividad/qsv/files/NYC_311_SR_2010-2020-sample-1M.7z
摘要:
测试对比了DuckDB中rusty_sheet与官方excel插件读取Excel文件的性能。结果显示,rusty_sheet在功能和速度上全面超越官方插件:
功能优化:支持更准确的数据类型推断(如int64而非double),且能处理百万行数据(如104万行的exli2.xlsx)。
性能优势:读取同一文件时,rusty_sheet耗时19.667秒,官方插件耗时26.6秒,提升约26%。小型文件(如20行的pysale20.xlsx)也显示类似趋势。
兼容性:支持中文表头等复杂场景,且数据解析更精准(如日期格式)。
容错性:对于首行空白列,只要设置header=false就能正确解析。

1071

被折叠的 条评论
为什么被折叠?



