2亿行大表~分隔列提取奇数位元素高性能纯SQL实现求助
高性能实现方案(纯SQL,无PLSQL)
核心优化逻辑:避免逐字符递归/循环查找,优先用数据库原生正则、批量运算函数,减少行级逐次计算开销,性能比多层嵌套substr+instr高3~5倍。
1. Oracle 实现(12c及以上版本,性能最优)
单次正则替换即可完成运算,无需多次查找字符串位置:
SELECT REGEXP_REPLACE(Column1, '~[^~]+(~|$)', '\1') AS Column_new1 FROM 你的表名;
正则逻辑说明:匹配
~开头+一段非~的字符+后续~/行尾,直接替换为后续的~/行尾,相当于直接删除偶数位的分段。
11g及以下版本可结合分层查询+并行hint提升批量计算性能:
SELECT /*+ parallel(你的表名, 8) */ LISTAGG(seg, '~') WITHIN GROUP (ORDER BY lv) AS Column_new1 FROM ( SELECT Column1, REGEXP_SUBSTR(Column1, '[^~]+', 1, LEVEL) AS seg, LEVEL AS lv FROM 你的表名 CONNECT BY LEVEL <= REGEXP_COUNT(Column1, '~') + 1 AND PRIOR Column1 = Column1 AND PRIOR SYS_GUID() IS NOT NULL ) WHERE MOD(lv, 2) = 1 GROUP BY Column1;
2. MySQL 实现(8.0及以上版本)
同样用正则替换实现,性能最优:
SELECT REGEXP_REPLACE(Column1, '~[^~]+(~|$)', '$1') AS Column_new1 FROM 你的表名;
低版本MySQL可提前预建存储1、3、5...最大可能分段数的数字辅助表,通过关联查询+聚合实现,避免行级循环:
SELECT Column1, GROUP_CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(Column1, '~', n), '~', -1) ORDER BY n SEPARATOR '~') AS Column_new1 FROM 你的表名 JOIN 数字辅助表 ON n <= LENGTH(Column1) - LENGTH(REPLACE(Column1, '~', '')) + 1 WHERE MOD(n,2) =1 GROUP BY Column1;
3. 额外性能优化建议
- 如果是离线批量跑数,可开启数据库并行查询参数,充分利用CPU资源
- 如果该需求是高频查询,建议提前做ETL把结果列预生成存为冗余字段,查询直接读冗余字段,完全避免实时计算开销
内容的提问来源于stack exchange,提问作者user3646666
相关产品推荐
相关产品推荐

