You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化含多CASE WHEN语句的SQL查询以提升执行效率?

优化含多CASE WHEN的SQL查询性能

我编写的SQL查询包含多个CASE WHEN语句,每个CASE里重复执行相同的子查询,导致代码运行耗时过长,希望找到更优的写法来优化该查询。

原查询代码:

SELECT equipment_id 

, CASE  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 100001 AND equipment_id = e.equipment_id) = '3qwe' 
  THEN 'Table 1.1-2, ' 
  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 100001 AND equipment_id = e.equipment_id) = '6qwe' 
  THEN 'Table 1.2-2, ' 
  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 100001 AND equipment_id = e.equipment_id) = '6qre' 
  THEN 'Table 1.2-3, '
  ELSE NULL 
  END table_number
  
, CASE  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 14 AND equipment_id = e.equipment_id) = 'gas' 
  THEN 'Gas Powered ' 
  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 14 AND equipment_id = e.equipment_id) = 'electric' 
  THEN 'Electric Powered '
  ELSE NULL 
  END power_type
  
, CASE  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 100001 AND equipment_id = e.equipment_id) = '3qwe' 
  THEN '3-round, west' 
  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 100001 AND equipment_id = e.equipment_id) = '6qwe' 
  THEN '6 round, west '  
  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 100001 AND equipment_id = e.equipment_id) = '6qre' 
  THEN '6-round, east' 
  WHEN (SELECT LOWER(to_char(equipment_type)) FROM equipment_type WHERE equipment_type_id = 100001 AND equipment_id = e.equipment_id) = 'n/a'    
  THEN '(<= 200 mg)' 
  ELSE NULL 
  END  rating_class

 
FROM equipment e

优化方案

1. 提前关联数据,避免重复子查询

将重复查询的equipment_type数据通过LEFT JOIN一次性取出,每个equipment_id只查询一次对应类型的数据,大幅减少数据库IO操作:

SELECT 
    e.equipment_id,
    CASE 
        WHEN et1.type_value = '3qwe' THEN 'Table 1.1-2, '
        WHEN et1.type_value = '6qwe' THEN 'Table 1.2-2, '
        WHEN et1.type_value = '6qre' THEN 'Table 1.2-3, '
        ELSE NULL 
    END table_number,
    CASE 
        WHEN et2.type_value = 'gas' THEN 'Gas Powered '
        WHEN et2.type_value = 'electric' THEN 'Electric Powered '
        ELSE NULL 
    END power_type,
    CASE 
        WHEN et1.type_value = '3qwe' THEN '3-round, west'
        WHEN et1.type_value = '6qwe' THEN '6 round, west '
        WHEN et1.type_value = '6qre' THEN '6-round, east'
        WHEN et1.type_value = 'n/a' THEN '(<= 200 mg)'
        ELSE NULL 
    END rating_class
FROM equipment e
LEFT JOIN (
    SELECT 
        equipment_id,
        LOWER(to_char(equipment_type)) AS type_value
    FROM equipment_type
    WHERE equipment_type_id = 100001
) et1 ON e.equipment_id = et1.equipment_id
LEFT JOIN (
    SELECT 
        equipment_id,
        LOWER(to_char(equipment_type)) AS type_value
    FROM equipment_type
    WHERE equipment_type_id = 14
) et2 ON e.equipment_id = et2.equipment_id;

2. 使用CROSS APPLY简化关联(适用于SQL Server、PostgreSQL等)

通过APPLY子查询一次性获取当前equipment_id对应的两种类型值,减少关联次数:

SELECT 
    e.equipment_id,
    CASE 
        WHEN et.type_100001 = '3qwe' THEN 'Table 1.1-2, '
        WHEN et.type_100001 = '6qwe' THEN 'Table 1.2-2, '
        WHEN et.type_100001 = '6qre' THEN 'Table 1.2-3, '
        ELSE NULL 
    END table_number,
    CASE 
        WHEN et.type_14 = 'gas' THEN 'Gas Powered '
        WHEN et.type_14 = 'electric' THEN 'Electric Powered '
        ELSE NULL 
    END power_type,
    CASE 
        WHEN et.type_100001 = '3qwe' THEN '3-round, west'
        WHEN et.type_100001 = '6qwe' THEN '6 round, west '
        WHEN et.type_100001 = '6qre' THEN '6-round, east'
        WHEN et.type_100001 = 'n/a' THEN '(<= 200 mg)'
        ELSE NULL 
    END rating_class
FROM equipment e
CROSS APPLY (
    SELECT 
        MAX(CASE WHEN equipment_type_id = 100001 THEN LOWER(to_char(equipment_type)) END) AS type_100001,
        MAX(CASE WHEN equipment_type_id = 14 THEN LOWER(to_char(equipment_type)) END) AS type_14
    FROM equipment_type et
    WHERE et.equipment_id = e.equipment_id
      AND et.equipment_type_id IN (14, 100001)
) et;

3. 添加索引提升查询效率

在equipment_type表上创建复合索引,让数据库能快速定位目标数据:

CREATE INDEX idx_equipment_type_id_eqid ON equipment_type(equipment_type_id, equipment_id, equipment_type);

内容的提问来源于stack exchange,提问作者Erin Lim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 22:04:53