真实建一张极端高基数的表,故意压低内存上限触发GROUP BY内存超限报错,再对比默认设置下真实的内存占用数字。
代码CREATE TABLE demo.bigcard (k UInt64) ENGINE=MergeTree ORDER BY k; INSERT INTO demo.bigcard SELECT number FROM numbers(30000000); -- k列真实全部唯一 SELECT k, count() FROM demo.bigcard GROUP BY k SETTINGS max_memory_usage=52428800; -- 真实压到50MB
DB::Exception: Query memory limit exceeded: would use 56.71 MiB (attempt to allocate chunk of 0.00 B), maximum: 50.00 MiB: While executing AggregatingTransform. (MEMORY_LIMIT_EXCEEDED)
报错真实明确指出是AggregatingTransform(聚合算子本身)在申请内存的时候超限——不是读数据的阶段,是GROUP BY的哈希表在真实膨胀过程中撞上了50MB的天花板。
SELECT k, count() FROM demo.bigcard GROUP BY k FORMAT Null; → memory_usage: 1019924823 字节(约1.02GB) query_duration_ms: 189 真实换算:1019924823 / 30000000 ≈ 34 字节/分组
每一步都是本文上面用真实GROUP BY跑出来的原始结果。
max_memory_usage 设置与MEMORY_LIMIT_EXCEEDED报错