SQL查询优化求助:CASE语句与CONCAT操作优化方案(Hadoop环境)
SQL优化方案(针对CASE语句与CONCAT操作)
一、CASE语句优化
你的CASE语句存在重复计算字符串截取和条件冗余的问题,以下是两种高效优化写法:
写法1:合并相同结果的条件(用IN简化)
把返回相同值的条件合并,同时用LEFT()替代SUBSTRING()(语法更简洁,Hadoop系SQL引擎对LEFT的执行优化更友好):
CASE WHEN LEFT(ZSYTMM_AE1.LIFNR, 2) IN ('10', '11', '12') THEN 'VI' WHEN LEFT(ZSYTMM_AE1.LIFNR, 2) IN ('13', '14') THEN 'MI' END AS reference_type
写法2:用范围判断进一步简化
因为LIFNR前两位是连续的数值型字符串,可直接用BETWEEN做范围匹配,减少条件分支:
CASE WHEN LEFT(ZSYTMM_AE1.LIFNR, 2) BETWEEN '10' AND '12' THEN 'VI' WHEN LEFT(ZSYTMM_AE1.LIFNR, 2) BETWEEN '13' AND '14' THEN 'MI' END AS reference_type
进阶优化:提前计算公共字段
如果查询涉及更多基于LIFNR前两位的逻辑,可以在子查询/CTE中先提取该字段,避免多次调用字符串函数:
WITH base_data AS ( SELECT ZSYTMM_AE1.*, LEFT(ZSYTMM_AE1.LIFNR, 2) AS lifnr_prefix, CONCAT(ZSYTMM_AE1.NUMNF, 'A', ZSYTMM_AE1.SERIE) AS combined_receipt FROM dl_edge_base_sapprdmerc_11324_base_prd_sapr3.ZSYTMM_AE1 ZSYTMM_AE1 ) SELECT combined_receipt AS receipt, combined_receipt AS external_receipt, zsytsd_pa_plant.plant AS plant, base_data.LIFNR AS suppliercode, CASE WHEN lifnr_prefix BETWEEN '10' AND '12' THEN 'VI' WHEN lifnr_prefix BETWEEN '13' AND '14' THEN 'MI' END AS reference_type FROM base_data INNER JOIN dl_edge_base_sapprdmerc_11324_base_prd_sapr3.zsytsd_pa_plant zsytsd_pa_plant ON base_data.werks = zsytsd_pa_plant.plant
二、CONCAT操作优化
你当前查询中receipt和external_receipt是完全相同的拼接结果,重复执行了两次CONCAT操作,会额外消耗CPU和IO资源。
优化核心是提前计算一次拼接结果(如上述CTE中的combined_receipt),后续直接引用即可,避免重复执行字符串拼接逻辑。
三、Hadoop环境额外提速建议
针对Hadoop(Hive/Spark SQL)环境,这些操作能进一步缩短查询耗时:
- 确认表是否采用列式存储格式(如ORC/Parquet),列式存储可大幅减少扫描的数据量
- 检查JOIN字段
werks是否有统计信息,无统计信息时执行ANALYZE TABLE ... COMPUTE STATISTICS,帮助优化器生成更优执行计划 - 若表数据量极大,确认是否按
werks或过滤字段做了分区,避免全表扫描
内容的提问来源于stack exchange,提问作者Alfredo Huerta
相关产品推荐
相关产品推荐

