使用Trino SQL统计字符串列唯一单词(忽略数字)遇内存超限问题
Trino SQL统计字符串列中唯一单词(忽略数字)并解决内存不足问题
问题分析
原语句count(distinct v2themes)直接统计整列的distinct值,但每个字段包含多个带数字后缀的主题条目,导致distinct集合基数过大,触发内存超限错误。需要先拆分条目、提取纯单词,再进行去重统计。
解决方案
1. 精确统计唯一单词
先拆分字段为单个主题条目,再提取去掉数字后缀的单词,最后去重统计:
SELECT COUNT(DISTINCT REGEXP_REPLACE(theme_entry, ',\\d+$', '')) AS unique_themes FROM your_table CROSS JOIN UNNEST(SPLIT(v2themes, ';')) AS t(theme_entry) WHERE theme_entry != '' -- 过滤拆分后可能的空条目
SPLIT(v2themes, ';'):将每个字段按分号拆分成多个主题条目UNNEST:将拆分后的数组展开为单独的行REGEXP_REPLACE(theme_entry, ',\\d+$', ''):去掉每个条目末尾的逗号和数字,提取纯单词COUNT(DISTINCT ...):统计唯一单词数量
2. 大数据量下的近似统计(内存友好)
如果数据量极大,允许近似结果,可使用APPROX_DISTINCT降低内存占用:
SELECT APPROX_DISTINCT(REGEXP_REPLACE(theme_entry, ',\\d+$', '')) AS approx_unique_themes FROM your_table CROSS JOIN UNNEST(SPLIT(v2themes, ';')) AS t(theme_entry) WHERE theme_entry != ''
3. 分步聚合优化内存
也可以通过子查询先去重再统计,进一步减少内存压力:
SELECT COUNT(*) AS unique_themes FROM ( SELECT DISTINCT REGEXP_REPLACE(theme_entry, ',\\d+$', '') AS theme_word FROM your_table CROSS JOIN UNNEST(SPLIT(v2themes, ';')) AS t(theme_entry) WHERE theme_entry != '' ) AS theme_subquery
额外建议
若上述SQL优化后仍内存不足,可调整Trino集群的内存配置参数,例如:
- 增加
query.max-memory-per-node:单节点允许的最大查询内存 - 调整
query.max-total-memory-per-node:单节点允许的总查询内存(含溢出到磁盘的部分)
内容的提问来源于stack exchange,提问作者Son
相关产品推荐
相关产品推荐

