DuckDB实战:ICU 每秒都在产生数据,4.3 亿条记录怎么查
「ICU 数据量大」是个抽象说法。到底多大?
我们把自己的 MIMIC-IV 副本(从 PhysioNet 申请下载)转成 Parquet 后,跑了一遍统计。数字比想象的夸张。
● ● ●
一张表,4.3 亿行
4.3 亿行监护数据:Parquet 压缩 + 毫秒级查询
MIMIC-IV 里最大的一张表叫 chartevents,存的是监护仪数据:心率、血压、血氧、体温……每个 ICU 患者每秒都在产生记录。
4.33 亿行。
1.58 亿行的 labevents(化验结果)排第二,1000 万行的 datetimeevents(时间事件)排第三。光这三张表加起来,6 亿行。
整个 MIMIC-IV 的 Parquet 副本 9.2 GB,覆盖 hosp(住院)、icu(ICU)、ed(急诊)、derived(派生)、note(病历文本)、cxr(影像报告)六个模块。
● ● ●
4.3 亿行查询只要 0.03 秒
数据大是一回事,查得快是另一回事。
我们在 MacBook 上直接跑(无服务器、无索引、单机):
count(*) | 0.03s | |
WHERE itemid=220045 | 0.28s | |
count(DISTINCT subject_id) | 0.07s | |
| 0.51s |
这不是优化过的数据库,就是 DuckDB 直接读 Parquet 文件。为什么这么快?
第一,Parquet 是列式存储。 数据按列存,查询只读需要的列。count(*) 甚至只读文件的元数据(行数直接写在文件头),不需要扫数据。
第二,谓词下推。WHERE itemid=220045 时,DuckDB 在读取阶段就把不匹配的行块跳过了,只解压命中的部分。
第三,压缩。 4.33 亿行、每行十几个字段,原始 CSV 估计要 30-50 GB;Parquet 压缩后 1.7 GB。读 1.7 GB 比读 50 GB 快一个数量级,磁盘 IO 就是性能。
● ● ●
这些数据里藏着什么
4.3 亿行不是冷冰冰的数字,随便看几个就有意思:
- 心率平均值 86.2
(正常静息 60-100),ICU 患者的平均水平——因为重症患者很多在用药、在发烧、在应激 - 心率最值 1 到 296
——1 大概率是传感器脱落或记录错误,296 是极端心动过速。真实数据就是这样,脏值、缺失、异常并存 - 65,366 个不同患者
在 chartevents 里有记录(整个库 299,712 个患者)。只有进过 ICU 的患者才有监护数据
● ● ●
对我们做 AI 查询的意义
数据量大直接影响了我们怎么做 AI 问答(本系列第二篇的模板路线)。
第一,全表扫描不可怕,但没必要。 4.3 亿行全扫只要 0.03s,是因为 count(*) 读的是元数据。真做分析(JOIN、GROUP BY)还是要靠谓词下推把扫描范围缩小。我们的模板全部带 WHERE 条件(时间窗口、患者 ID),就是这个原因。
第二,模板必须预过滤。 「查患者 73713 的最近 5 条心率」,模板 SQL 是:
SELECT charttime, valuenum
FROM chartevents
WHERE subject_id = 73713 AND itemid = 220045
ORDER BY charttime DESC
LIMIT 5
subject_id 过滤在读取阶段就生效,4.3 亿行瞬间缩到几千行。LLM 直接写 SQL 容易漏掉 WHERE 条件,全表扫 4.3 亿行再排序,慢且容易超时。模板把「必须先过滤」写死在 SQL 里。
第三,大数据是评测的隐形维度。 我们评测 AI 答对没(本系列第八篇),31 题里的监控类查询(fluid_balance、ventilation)都是基于 chartevents 这种大表。小数据集上能跑的 SQL,在大表上可能超时、可能内存爆。评测题必须用真实规模的数据。
● ● ●
给做临床数据分析的人
- 01Parquet 是你的朋友
。4.3 亿行压到 1.7 GB,查询快一个数量级。MIMIC 官方给的是 CSV,转 Parquet 是本地化的第一步(本系列第一篇) - 02先看元数据再看数据
。 count(*)在 Parquet 上是 0.03s 不是因为它快,是因为行数写在文件头。别拿它当「查询性能」的证据 - 03谓词下推是性能第一来源
。WHERE 条件写在查询里,比事后过滤快几个数量级。AI 生成的 SQL 必须强制带过滤条件 - 04脏值要有心理准备
。心率 1 到 296,真实临床数据就是这样。统计前先做合法性过滤(我们用的是 valuenum 大于 0 且小于 300)
● ● ●
参考来源
- 01
MIMIC-IV 官方文档(chartevents 表说明):https://mimic.mit.edu/docs/iv/modules/icu/chartevents/ - 02
DuckDB 官方文档(Parquet 扫描与谓词下推):https://duckdb.org/docs/data/parquet/overview.html - 03
Apache Parquet 格式规范(列式存储):https://parquet.apache.org/docs/file-format/ - 04
本文统计基于本地 MIMIC-IV Parquet 副本(PhysioNet 申请),查询脚本:本系列实验数据