你有没有遇到过这种时刻:Excel 右下角一直在转圈,光标变成沙漏,你想小心翼翼复制两列数据,结果连粘贴都失灵,最后只能眼睁睁看着一台性能不错的电脑被一份几十 MB 的表格拖死。我之前在电商公司做数据处理,最怕的不是业务方提需求,而是他们发来一个“帮忙整理一下”的超大 Excel——动辄二三十万行,打开都要快一分钟,筛选一次感觉风扇要起飞。
后来我换成 DuckDB,才真正体会到大文件处理可以快到什么程度:十几万行、几十个工作表的数据,从读入到汇总,往往一两秒就出结果,而且全程不吃 Excel 半点资源。这篇东西不是写给纯程序员看的,是写给所有被 Excel 卡到怀疑人生的表哥表姐。我会讲清楚 DuckDB 为什么快、怎么装、怎么用,以及真正能把你的工作日救回来的那些细节和坑。如果你也想告别 Excel 卡死的循环,这篇就是给你准备的。
1. 先搞清楚一件事:Excel 卡死,是设计上的必然
1.1 Excel 的行数天花板与“百万行魔咒”
很多人以为 Excel 卡死是因为电脑太旧、内存太小,其实不完全是。Excel 从 2010 版开始,单个工作表的行数硬上限就是 1,048,576 行,列数是 16,384 列。这个限制写在产品设计里,不是换个高配电脑就能绕开的。也就是说,哪怕你手头的数据只有二十万行,Excel 也已经开始吃力了,因为它的底层并不是为这种规模的分析场景设计的。
Excel 本质是一个“电子表格”工具,它的核心使用方式是逐格编辑、实时计算、所见即所得。这种交互模型在几百行、几千行时非常好用,但一旦到了十万行级别,任何一次筛选、排序、查找都会触发整张表的重算。数据量越大,重算越慢,界面就越容易卡成“白屏+转圈”。碰上公式多、条件格式多、加载项多的文件,情况只会更糟。我见过有人把 VLOOKUP 写满十几万行,每次双击单元格都要等十秒,那种痛苦我很理解。
1.2 行式存储与“全量加载内存”的内存模型
再深一层说,Excel 保存文件时,数据是“行式组织”的,你要读某一个字段,它也得把整个文件的内容按顺序加载进内存。而且 Excel 打开文件时,默认会把整个工作簿都读进内存,包括所有工作表、所有格式、所有公式缓存。这意味着文件越大,占用的内存就越大,甚至可能出现“文件才 100MB,内存却吃掉 2GB”的夸张情况。
更糟糕的是,Excel 的很多计算是单线程的,也就是说它很难利用你 CPU 的多核优势去提高性能。你打开任务管理器会看到 CPU 占用可能只有 12%,但 Excel 依然卡得像冻住一样。这种“有力使不出”的架构,让超大 Excel 文件在 Excel 里基本是无解的。想从根上解决问题,就得换一个“分析的引擎”来处理数据,而不是继续在 Excel 里面硬扛。
1.3 那些诡异的 Bug(复制粘贴失灵、双击报错)和“卡死”是一回事
网上搜“excel无法复制粘贴”“excel复制粘贴没反应”“excel单元格复制后粘贴不了”,能看到大量求助帖。很多人以为自己操作错了,或者怀疑是 Office 安装坏了,其实绝大多数情况就是:Excel 这个大文件正忙到没空响应剪贴板,或者后台残留了多个 EXCEL.EXE 进程把资源占满了。还有“双击出现 这个操作只对当前安装的产品有效”这类报错,也经常出现在 Office 组件未正确注册、加载项冲突的环境里。
这些问题背后其实是一个共同的信号:Excel 在做它不擅长的事。当数据量超过几万行,继续用 Excel 去承担数据分析、批量清洗、多表合并这类任务,就是典型的“小马拉大车”。这也是我要推荐 DuckDB 的核心原因——它不依赖 Excel 打开文件,直接绕过这套卡顿机制,从源头把性能问题解决掉。
2. DuckDB 凭什么能“秒”处理大 Excel
2.1 列式存储 + 向量化执行:分析场景的降维打击
DuckDB 是一个嵌入式分析型数据库,你可以把它理解成一个“专门为数据处理和统计查询优化的数据库引擎”。它最大的特点有两个:列式存储和向量化执行。列式存储的意思是,数据在底层按“列”存放,查询某几列时只需要读取这几列的数据,不像 Excel 那样必须整行整行地扫。你要算“全公司每个部门的销售额总和”,DuckDB 只去读“部门”和“销售额”两列,其余十几列完全可以不碰。
向量化执行就更关键了。传统数据库是一条一条处理记录,DuckDB 是一次处理一批数据(通常是一批固定大小的向量),并且充分利用 CPU 的 SIMD 指令做并行计算。再加上它天然支持多核并行,对大文件的扫描、过滤、聚合都快得离谱。我用一台普通笔记本测过,读一个约 80MB 的 xlsx 文件,里面二十万行、三十多列,DuckDB 从读入到完成 GROUP BY 汇总,大概一到两秒;同样的事情放 Excel 里,光是筛选一次就要卡半分钟。
2.2 进程内数据库:零部署,一个文件搞定
DuckDB 是“进程内数据库”,也就是说它不需要像 MySQL、PostgreSQL 那样单独安装一个服务器,也不用配置 IP、端口、用户名、密码。它就是一个库,嵌入到你的 Python 程序、命令行工具,甚至 Java 或者 R 里面直接用。这个特点对普通办公场景太友好了:装好之后,你打开命令行敲个 duckdb,或者在自己的 Python 脚本里 import duckdb,就能立刻开始干活。
很多人一听到“数据库”三个字就害怕,觉得门槛很高。实际上 DuckDB 的使用体验非常接近“用 SQL 处理表格数据”。SQL 这门语言你可能没系统学过,但只要你用过 Excel 的数据透视表、SUMIFS、VLOOKUP,你已经理解了大半——剩下的就是把这些操作换成几行 SQL 语句的事。更妙的是,DuckDB 对 CSV、Parquet、JSON 也有原生的读取能力,配合 read_excel 扩展就能直接吃 xlsx 文件,完全不需要先转换格式。
2.3 和 pandas、openpyxl 放在一起比,优势在哪
处理 Excel 的 Python 方案里,最常被提起的是 pandas 和 openpyxl。pandas 确实强大,但它有个天生的毛病:读文件时会把数据整个塞进内存里的 DataFrame,文件一上 GB,内存立刻爆表,机器直接卡死。我踩过这个坑,用 pandas 读一个 1.2GB 的 xlsx,程序没跑完,电脑先休眠了。openpyxl 更惨,它对 xlsx 的解析是纯 Python 实现,底层没有做性能优化,读十万行都要十几秒到几十秒,更别提做聚合运算了。
DuckDB 和它们最大的区别是“超出内存也能算”。它有一套完善的落盘机制,当数据量超过内存时,会把中间结果临时写到磁盘上,继续完成计算。这就意味着你可以用一台 8GB 内存的老笔记本去处理几个 GB 的文件,这在 pandas 和 Excel 里几乎是不可能的。当然,DuckDB 也可以非常方便地和 pandas 互通:查询结果用 .df() 转成 DataFrame,或者把 DataFrame 注册成临时表让 DuckDB 去算,两边配合着用才是真实战中的最佳姿势。
2.4 说清楚边界:DuckDB 不是用来取代 Excel 的
这里必须泼一盆冷水:DuckDB 不会取代 Excel,也不该取代 Excel。它的定位是“分析计算引擎”,负责处理那些把 Excel 卡死的脏活累活——清洗、筛选、聚合、去重、合并、统计。但真正的“人机交互编辑”场景,比如你需要在某个单元格里调整格式、写备注、做图表、跟客户展示,那还是 Excel 的地盘。
所以正确的用法是:Excel 负责“给人看”,DuckDB 负责“替 Excel 算”。你需要分析一个超大文件时,别再用 Excel 硬打开了,先用 DuckDB 把结果算好,汇总成一个小巧的、几万行以内的结果表,再导回 Excel 去做展示和微调。这样既保住了 Excel 的交互优势,又把性能瓶颈彻底绕开。我自己的数据工作流现在基本都是这个模式,爽了很久了。
3. 准备环境:装好 DuckDB 并接上 Excel 扩展
3.1 三种安装方式,按需选择
DuckDB 的安装非常简单,主要看你平时习惯用什么工具。这里给出三种主流方式,任选其一即可:
Python 包(推荐给数据分析用户):执行
pip install duckdb,然后直接写 Python 脚本调用。我自己最常用的是这种方式,因为后面如果要配合 pandas、openpyxl 做点联动,全在同一个环境里,非常顺滑。命令行客户端(推荐给想快速试一下的人):去官网下载对应平台的 CLI 压缩包,解压后是一个可执行文件,直接运行就能进入 SQL 交互界面。优点是零依赖、启动快,适合在服务器或者临时环境里应急处理数据。
嵌入式嵌入到应用里:DuckDB 官方支持 Java、R、Node.js、Go 等多种语言。如果你在做系统开发,想要在应用内直接查询 Excel 或 CSV 数据,可以选对应语言的第三方包,调用方式和 Python 版大同小异。
安装完成之后,在命令行输入duckdb或者 Python 里执行import duckdb; print(duckdb.__version__),能出现版本号就说明装好了。我建议第一次用的人先装 Python 版,因为后面很多高级玩法都要靠 Python 配合。
3.2 安装并加载 excel 扩展
DuckDB 原生并不直接支持 xlsx,需要安装官方的 excel 扩展。这个过程比我预想的还要简单,只需要两行 SQL:
INSTALL excel; LOAD excel;如果是 Python 环境,就在连接后执行:
import duckdb con = duckdb.connect() con.execute("INSTALL excel; LOAD excel;") print("excel extension loaded")这里有几个细节值得说一下。第一,INSTALL只需要执行一次,扩展会下载到本地的扩展目录里,下次直接LOAD就行,离线也能用。第二,这个 excel 扩展目前是社区维护、官方合入的实验性扩展,功能还在持续迭代,但是日常读取 xlsx、做筛选聚合,稳定性已经足够用了。第三,如果你在公司内网、无法访问扩展下载源,可以到 DuckDB 社区的 GitHub Release 里手动下载对应平台和版本的扩展文件,放到本地扩展目录再加载。
3.3 读取第一个 Excel 文件
装好扩展之后,读 Excel 就是一条 SQL 的事,核心函数叫read_excel。假设你的桌面上有个orders.xlsx,里面是订单数据,第一个工作表叫“明细”,想读它的全部内容:
SELECT * FROM read_excel('/Users/yourname/Desktop/orders.xlsx', sheet='明细');如果你不指定 sheet,DuckDB 会默认读取第一个工作表。如果是批量读多个文件,还可以用通配符:
SELECT * FROM read_excel('/Users/yourname/Desktop/data/*.xlsx');想看看一个文件里到底有哪些工作表,可以用list_sheets参数:
SELECT * FROM read_excel('/Users/yourname/Desktop/orders.xlsx', list_sheets=true);第一次跑通的那一刻,你会明显感觉到和 Excel 完全不同的节奏:文件几乎没有“打开”的过程,读出来就直接进入 SQL 查询的状态,想怎么算就怎么算。那种喝口水的功夫结果已经出来的感觉,真的非常解压。
3.4 .xls 老文件怎么兼容,以及真实的依赖说明
需要注意的是,read_excel对.xlsx(Excel 2007 之后的新格式)支持得很好,但遇到老式的.xls格式时,处理逻辑会复杂一些。这个扩展早期版本在部分平台上会依赖 LibreOffice 把.xls转成中间格式再读取,所以如果你手头有一堆老.xls文件,我一般会有两个选择:要么用 Excel/WPS 批量另存为.xlsx,要么干脆在 DuckDB 里先只读.xlsx,老文件统一做一次格式整理。
提示:如果你读一个
.xls文件报错,先别急着怪 DuckDB,90% 的情况是格式兼容问题。最简单的解决方案就是用 WPS 或者 Office 批量转成.xlsx。如果文件非常多,可以写个 Python 小脚本,用 pyexcel 或者 xlrd 批量转换,一次性解决。
不过话说回来,现在几乎所有的业务数据导出都是.xlsx了,xls只在远古系统里还会出现。我平时接到的任务,99% 是.xlsx,所以这一点不太需要纠结。
4. 高频 Excel 需求,换 DuckDB 怎么写
4.1 多条件筛选:告别转圈
Excel 里做多条件筛选,要么用筛选按钮一层一层点,要么用高级筛选自己写条件区域。数据少的时候没问题,数据一多,每次筛选都像在赌运气。DuckDB 里这就是一个最简单不过的 WHERE 子句。假设订单表里有日期、省份、金额、状态四列,你要找出“2024 年 1 月之后、广东或浙江、已完成”的所有订单:
SELECT * FROM read_excel('/Users/yourname/Desktop/orders.xlsx', sheet='明细') WHERE 订单日期 >= DATE '2024-01-01' AND 省份 IN ('广东', '浙江') AND 订单状态 = '已完成';你可以把结果直接复制到 CSV,也可以再往下做汇总,一次筛选不够就再套一层查询。最关键的是,这个筛选过程不会动原文件,你不需要反复“另存为”,也不用担心筛选破坏了原始数据。对做业务的人来说,这等于拿到了一个永远不会“手滑改坏原表”的安全环境。
4.2 两列查重与全表去重,比删除重复项更可控
网上关于“excel 两列如何进行查重”的求助特别多。Excel 自带的删除重复项功能,用起来总是心里没底,因为它会直接改原表,而且你很难搞清楚它到底按哪几列去重。DuckDB 里做查重,思路非常清晰:先分组,再数一数每组有几条。
比如你要找出销售表里“客户手机号”出现超过一次的记录:
SELECT 手机号, COUNT(*) AS 出现次数 FROM read_excel('/Users/yourname/Desktop/customers.xlsx') GROUP BY 手机号 HAVING COUNT(*) > 1;如果要做“两列交叉查重”,也就是看表 A 和表 B 里有没有相同手机号,用 JOIN 就行:
SELECT a.*, b.* FROM read_excel('/Users/yourname/Desktop/a.xlsx') a JOIN read_excel('/Users/yourname/Desktop/b.xlsx') b ON a.手机号 = b.手机号;这种写法比 Excel 里的 VLOOKUP 直观多了,而且速度是真的秒级。查重结果你还能继续加工,比如统计重复率、去重后的总数,一条 SQL 全搞定,不用担心“删了又后悔”的问题。
4.3 SUMIFS、COUNTIFS 的公式,用 SQL 平替
Excel 里,SUMIFS 和 COUNTIFS 是高频函数,公式写长了又难读又难维护。尤其是“满足多个条件求总和”“按条件计数”这类需求,在 DuckDB 里用SUM(CASE WHEN ...)和COUNT_IF就能完美替代。举一个例子:统计“已完成订单的总金额”和“金额超过 100 的订单数量”:
SELECT SUM(CASE WHEN 订单状态 = '已完成' THEN 订单金额 ELSE 0 END) AS 已完成金额, COUNT_IF(订单金额 > 100) AS 大额订单数 FROM read_excel('/Users/yourname/Desktop/orders.xlsx');你要是想按省份分组统计,加一个 GROUP BY 就行:
SELECT 省份, SUM(订单金额) AS 销售额, COUNT(*) AS 订单数 FROM read_excel('/Users/yourname/Desktop/orders.xlsx') GROUP BY 省份 ORDER BY 销售额 DESC;这个结果其实就已经是“数据透视表”的雏形了。我经常跟朋友开玩笑说,学 DuckDB 不用专门学 SQL 语法,你只要会 SUMIFS、透视表和 VLOOKUP,DuckDB 的 80% 常用功能你已经“翻译”得七七八八了。剩下那 20%,跑几个例子就顺手了。
4.4 字符串搜索、清洗与分列一步到位
Excel 里做字符串查找,用 FIND、LEFT、MID 这些函数。跑到大数据量时,这些函数也扛不住。DuckDB 提供了一整套字符串函数,支持模糊匹配和正则表达式。比如想找出所有备注里包含“加急”的订单:
SELECT * FROM read_excel('/Users/yourname/Desktop/orders.xlsx') WHERE 备注 LIKE '%加急%';更狠的是正则处理。比如手机号和电话号码混在一个字段里,想提取数字串,Excel 里要写很长的数组公式,而在 DuckDB 里可以这样:
SELECT REGEXP_REPLACE(联系方式, '\D', '', 'g') AS 干净号码 FROM read_excel('/Users/yourname/Desktop/customers.xlsx');分列需求也一样。比如地址是“广东省-深圳市-南山区”这样的格式,想拆成三列,用split_part就可以:
SELECT split_part(完整地址, '-', 1) AS 省份, split_part(完整地址, '-', 2) AS 城市, split_part(完整地址, '-', 3) AS 区县 FROM read_excel('/Users/yourname/Desktop/addr.xlsx');这些操作全部不修改原文件,只管返回结果,出一份新数据就多一层保险。清洗类工作用 DuckDB 做,比在 Excel 里一步步拖拽复制要安全得多。
4.5 多工作表、多文件批量合并
真实业务里最让我头疼的,不是单个大文件,而是“几十个小文件还要合并”。比如运营把一年 12 个月的报表拆成 12 个 Excel,每个还有好几个 sheet,你手工合并得复制粘贴到手酸。DuckDB 处理这件事,又是通配符加一条 SQL:
SELECT * FROM read_excel('/Users/yourname/Desktop/report/month_*.xlsx', union_by_name=true);union_by_name=true的意思是,如果一个表有“省份”列而另一个表叫“省”,只要你开启这个参数,DuckDB 会尽量按列名对齐合并;如果列结构完全一致,不加这个参数直接合并也行。要是不同月份的文件里,列顺序还不一样,union_by_name 就是你的救星。
如果每个文件里有多个 sheet,想全部读出来,也可以先列出每个文件的所有 sheet,再批量处理。我通常会在 Python 里写个循环,遍历 glob 匹配到的文件列表,逐一指定 sheet 读取,最后UNION ALL BY NAME合并成一张大表。这套流程放在以前用 Excel,得开一个超大工作簿然后不停地复制,现在写一次脚本,以后每个月重复用同一个套路就行。
4.6 把结果导回 Excel 能用的格式
DuckDB 的 excel 扩展目前主打“读取”,写回 xlsx 不是它的亮点,所以我大部分时候会把计算结果导出成 CSV,再用 Excel 打开。好在 CSV 这个格式 Excel 完全兼容,而且导出大数据量时比 xlsx 更快更稳。导出语法如下:
COPY ( SELECT 省份, SUM(订单金额) AS 销售额 FROM read_excel('/Users/yourname/Desktop/orders.xlsx') GROUP BY 省份 ) TO '/Users/yourname/Desktop/汇总.csv' WITH (HEADER true, DELIMITER ',');如果希望最终交付的是格式好看的 Excel 报表,我的习惯是:用 DuckDB 算出干净的明细或汇总数据,导出 CSV,然后交给 Excel 模板或者 Python 的 openpyxl 去生成最终文件。这样分工很明确——DuckDB 负责算得快,Excel 负责长得好看,两个工具各干各擅长的,谁也不卡谁。
如果你人在 Python 环境里,更轻松的做法是直接把查询结果转成 pandas DataFrame,再一行df.to_excel()写回。需要注意 pandas 写 Excel 需要 openpyxl 或 xlsxwriter 作为后端,提前pip install openpyxl就行。这个组合我实测下来很稳,尤其适合要生成带格式报表的场景。
5. 常见问题与排查技巧实录
5.1 路径、扩展名和权限的坑
用 read_excel 读文件,报错最多的就是路径问题。Windows 用户尤其容易踩反斜杠的坑,比如'C:\Users\张三\桌面\orders.xlsx'在 Python 字符串里会转义出问题,建议统一用正斜杠或者pathlib构造路径。另外,中文路径和中文文件名在部分旧版本扩展上会有兼容问题,如果遇到“文件打不开”但路径明明没问题,可以试着把文件复制到纯英文目录再读。
还有一类问题是“文件被 Excel 占用”。如果你这个 xlsx 正开在 Excel 里,DuckDB 读它时,Windows 上可能因为文件锁定而报权限错误。所以在用 DuckDB 处理前,养成先关掉对应 Excel 文件的习惯,能省不少麻烦。这也是 DuckDB 天然的优势——它完全独立于 Excel 运行,不需要 Excel 参与,但反过来,如果 Excel 那个进程把文件锁死了,该让路还是得让路。
5.2 中文乱码与类型冲突
读 xlsx 出现中文乱码的概率比较低,因为 xlsx 内部本来就是 Unicode 编码,DuckDB 读取时会处理好。真正容易遇到的问题反而是“类型混乱”:同一个工作表里,某一列前几百行是数字,后面某几行变成了文本(比如手机号被存成“1.39E+10”这种科学计数法文本),DuckDB 在做类型推断时可能会报错,或者把整列都转成 VARCHAR。
遇到这种脏数据,最稳妥的办法是让所有列都按文本读入,之后再用 SQL 自己转换:
SELECT * FROM read_excel('/Users/yourname/Desktop/orders.xlsx', all_varchar=true);all_varchar=true会把所有列都当作文本处理,再配合CAST(列名 AS BIGINT)、TRY_CAST等函数精确转型。虽然多了一步转换,但至少不会因为某一行脏数据让整个查询崩掉。这在处理业务方交付的数据时,几乎是必备参数。
5.3 查询也慢?先检查这几个默认值
理论上 DuckDB 读 xlsx 已经很快了,但如果你遇到“查询也卡”的情况,优先级检查这三点。第一,是不是忘了开扩展?没LOAD excel时是会报错的,不存在慢的问题。第二,是不是数据量远超预期?xlsx 文件虽然只有 80MB,解压后内部 XML 可能有好几个 GB,如果机器内存太小,可以把临时文件目录指到 SSD 上,设置方式是在连接时加上PRAGMA temp_directory='/path/to/tmp';。第三,是不是正则或者模糊匹配写得太随意?LIKE '%关键词%'这种写法无法利用索引,在千万行级别上会比精确匹配慢一些,但这种规模在 xlsx 场景里很少见,一般不用太担心。
5.4 Excel 端“复制粘贴失灵”的应急恢复
如果你现在已经被卡死的 Excel 困住了,最简单的应急办法是先不要强行操作窗口,打开任务管理器,找到所有 EXCEL.EXE 进程,逐个结束掉。如果文件没保存,确实会丢失未保存内容,但总比整个系统崩溃强。之后重启 Excel,再打开文件时建议先用“打开并修复”或者只读方式,避免加载项干扰。
防止以后再发生同类问题,核心思路就是我今天说的:别让 Excel 打开那些大象文件。我也建议有条件的同学把文件另存为 xlsx 格式的同时,备份一份 CSV 或者 Parquet。这样即便哪天 Excel 又闹脾气,你至少能用 DuckDB 快速把数据捞出来,不会陷入“文件打不开就什么都干不了”的绝境。
5.5 一张速查表:Excel 操作 → DuckDB 语句
为了方便你入门,我把最常见的 Excel 操作和对应的 DuckDB 写法整理成了一张对照表:
| Excel 操作 | DuckDB 写法 | 备注 |
|---|---|---|
| 打开/查看数据 | SELECT * FROM read_excel('文件.xlsx'); | 秒开,不占用 Excel |
| 多条件筛选 | SELECT * FROM read_excel(...) WHERE 列1=... AND 列2>...; | 不修改原文件 |
| 去掉重复项 | SELECT DISTINCT 列1,列2 FROM read_excel(...); | 也可 GROUP BY |
| 查找重复值 | GROUP BY 列 HAVING COUNT(*)>1 | 直接列出重复记录 |
| SUMIFS 多条件求和 | SELECT SUM(CASE WHEN ... THEN ... END) FROM ...; | 灵活组合条件 |
| COUNTIFS 多条件计数 | SELECT COUNT_IF(条件) FROM ...; | 直接返回数量 |
| VLOOKUP 关联匹配 | SELECT * FROM a JOIN b ON a.键 = b.键; | 多表 JOIN 更清晰 |
| 数据透视表汇总 | SELECT 分类, SUM(数值) FROM ... GROUP BY 分类; | 结果透明可复现 |
| 文本查找 | WHERE 列 LIKE '%关键词%'; | 支持通配符 |
| 正则提取/清洗 | REGEXP_REPLACE(列, 模式, 替换); | 处理脏数据神器 |
| 导出结果 | COPY (查询语句) TO '结果.csv' WITH (HEADER true); | 也可转 pandas 再写 Excel |
这张表我建议你收藏起来,遇到想不起来的时候瞄一眼,绝对比满世界翻 Excel 函数教程快得多。
6. 我踩过的坑,和最后想说的几句
6.1 all_varchar 的妙用:先当文本读,再慢慢转型
我自己刚开始用 DuckDB 读 Excel 时,吃过一次大亏:一个几十万行的客户表,里面有个“客户编号”列,大部分是数字,但偏偏有几行是“ABC123”这种混着字母的编码。默认类型推断把这一列推断成了 BIGINT,读到那几行脏数据时直接报错中断。后来我学乖了,凡是这个来源的 Excel,一律先加all_varchar=true,把数据原样读出来,之后再用TRY_CAST或者CASE WHEN逐个处理。这个方法我强烈建议你也养成习惯,尤其是处理“人传人”的 Excel 文件,脏数据是常态,干净数据才是意外。
6.2 别让 DuckDB 干它不适合的活
DuckDB 不是万能的,我交过学费之后才明白边界在哪里。第一,它不适合做“单元格级编辑”,比如你要把某一行某个单元格单独改一下,那还是 Excel 的活儿。第二,它不适合作为多人并发写入的在线业务库,它是分析型引擎,不是事务型系统,别硬拿来当 MySQL 用。第三,它本身也不负责图表展示,分析完的结果还是得回归到 Excel、BI 工具或者前端页面。
正确的心态是:把 DuckDB 当成一个“数据加工车间”,原料是 Excel/CSV,车间负责清洗和计算,成品是干净的汇总表或者 CSV。它帮你解决的是中间那段最耗时、最容易卡死、最不需要人工干预的工作。认清这个边界,你的工作效率才会真的起飞。
6.3 自动化:一次写好,以后躺着用
我最喜欢 DuckDB 的另一个原因是,它特别好“脚本化”。你可以在一个 Python 脚本里写好一连串 SQL,把某个 Excel 文件的清洗、汇总、导出一次跑完,然后丢给任务计划程序(Windows 的任务计划或 macOS 的 crontab),每周自动执行。这样每周别人还在手工复制粘贴的时候,你这边已经自动生成好当周报表,并且直接发到了指定目录。
我自己的一个小习惯是:每个固定报表任务,都会在脚本开头写一行注释,注明“源文件放哪里、结果输出到哪里、跑挂了我大概哪里出了问题”。这样即使三个月后我忘了这个脚本的逻辑,临时有人接手也能快速搞清楚。DuckDB 的 SQL 足够直观,配合良好的注释,这种小自动化项目基本不需要额外维护成本。
6.4 从哪开始学,怎么进一步提升
如果你被这篇文章勾起了兴趣,我建议按这个顺序来:先把环境装好,用一个小一点的 Excel 试读一次;然后把第 4 节里的那几张表内容,挨个用自己的数据跑一遍;最后挑一个你日常最烦的 Excel 场景,尝试用 DuckDB 完整地替代一次。等你觉得顺手了,再去看官方文档里关于 Parquet、JSON、HTTPFS 扩展的介绍,那又是另一片新世界。
提示:DuckDB 官方文档质量很高,里面有很多可以直接复制运行的示例。遇到函数不会写,直接在文档搜函数名,通常都能找到用法和参数说明。刚开始别贪多,把 read_excel、GROUP BY、JOIN、COPY 这几个核心功能吃透,就足够应对 90% 的“Excel 太大处理不了”问题了。
最后再分享一点我个人的体会:工具永远是为解决问题服务的,学 DuckDB 不是为了显得多酷,而是为了让你在面对“20 万行 Excel”时不再手心冒汗。真正救你的是一个能处理大数据的可靠流程——统计、聚合、清洗都交给 DuckDB,Excel 只负责最后优雅的交付。这套流程跑通之后,你再回头看那些“Excel 无法复制粘贴”“双击没反应”的帖子,八成只会会心一笑:不是 Excel 不好,是它终于不必再被硬塞那些它扛不动的大活了。