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

优化Unpivot脚本:改用Cross Apply提升后端数据提取效率

SQL查询优化方案:替换Unpivot提升数据提取效率

当前使用Unpivot的脚本从后端提取数据耗时较长,希望改用Cross Apply或其他方式优化数据提取效率,原脚本如下:

SELECT 
    cm.cust_acct_no as "dd",
    ( 
    SELECT
        COALESCE(sum((select kca.active_account from kyc_count_account kca where kca.CUST_ACCT_NO = joint_acct)),0,0)
      FROM
        (SELECT
          (lpad('0', (16-length(t.link_cua_acno_01)), '0')||t.link_cua_acno_01) AS acct01
          ,(lpad('0', (16-length(t.link_cua_acno_02)), '0')||t.link_cua_acno_02) AS acct02
          ,(lpad('0', (16-length(t.link_cua_acno_03)), '0')||t.link_cua_acno_03) AS acct03
          ,(lpad('0', (16-length(t.link_cua_acno_04)), '0')||t.link_cua_acno_04) AS acct04
          ,(lpad('0', (16-length(t.link_cua_acno_05)), '0')||t.link_cua_acno_05) AS acct05
          ,(lpad('0', (16-length(t.link_cua_acno_06)), '0')||t.link_cua_acno_06) AS acct06
          ,(lpad('0', (16-length(t.link_cua_acno_07)), '0')||t.link_cua_acno_07) AS acct07
          ,(lpad('0', (16-length(t.link_cua_acno_08)), '0')||t.link_cua_acno_08) AS acct08
        FROM cbsdbap1.cusvcc t
        WHERE substr(t.key_1,4,16) = cm.cust_acct_no and t.code = 'CC' and rownum <= 1
    ) temp unpivot include NULLS (joint_acct FOR kind IN (acct01, acct02, acct03, acct04, acct05, acct06, acct07, acct08))) as "Number of Joint Accounts"
  FROM CUSM cm

可行调优方案

1. 用CROSS APPLY替换Unpivot,重构子查询逻辑

原脚本的嵌套Unpivot和多层子查询会引发多次表扫描,改用CROSS APPLY直接将多列转成行,同时把嵌套的kyc_count_account查询改为JOIN,减少重复查询开销:

SELECT 
    cm.cust_acct_no AS "dd",
    COALESCE(SUM(kca.active_account), 0) AS "Number of Joint Accounts"
FROM CUSM cm
LEFT JOIN cbsdbap1.cusvcc t 
    ON SUBSTR(t.key_1,4,16) = cm.cust_acct_no 
    AND t.code = 'CC'
CROSS APPLY (
    SELECT LPAD(t.link_cua_acno_01, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_01 IS NOT NULL
    UNION ALL
    SELECT LPAD(t.link_cua_acno_02, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_02 IS NOT NULL
    UNION ALL
    SELECT LPAD(t.link_cua_acno_03, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_03 IS NOT NULL
    UNION ALL
    SELECT LPAD(t.link_cua_acno_04, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_04 IS NOT NULL
    UNION ALL
    SELECT LPAD(t.link_cua_acno_05, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_05 IS NOT NULL
    UNION ALL
    SELECT LPAD(t.link_cua_acno_06, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_06 IS NOT NULL
    UNION ALL
    SELECT LPAD(t.link_cua_acno_07, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_07 IS NOT NULL
    UNION ALL
    SELECT LPAD(t.link_cua_acno_08, 16, '0') AS joint_acct FROM DUAL WHERE t.link_cua_acno_08 IS NOT NULL
) accts
LEFT JOIN kyc_count_account kca 
    ON kca.CUST_ACCT_NO = accts.joint_acct
GROUP BY cm.cust_acct_no;

优化点说明:

  • 用JOIN+CROSS APPLY替代多层嵌套结构,降低执行计划的复杂度
  • 用LPAD(col,16,'0')简化补零逻辑,比原脚本先计算长度再拼接更高效
  • 将单行查询kyc_count_account改为批量JOIN,减少多次单条查询的IO消耗

2. 添加索引优化查询速度

针对查询中用到的过滤和关联字段创建索引,大幅提升查找效率:

  • 给cbsdbap1.cusvcc表创建复合索引:CREATE INDEX idx_cusvcc_key1_code ON cbsdbap1.cusvcc(key_1, code);
  • 给kyc_count_account表创建索引:CREATE INDEX idx_kyc_cust_acct ON kyc_count_account(CUST_ACCT_NO);
  • 给CUSM表的cust_acct_no字段创建索引(若未存在):CREATE INDEX idx_cusm_cust_acct ON CUSM(cust_acct_no);

3. 简化过滤条件

原脚本用SUBSTR(t.key_1,4,16) = cm.cust_acct_no,如果key_1的结构固定为前3位+16位账号,可在cusvcc表新增计算列存储截取后的账号,再给计算列建索引,避免每次查询执行SUBSTR函数:

ALTER TABLE cbsdbap1.cusvcc ADD cust_acct_no AS SUBSTR(key_1,4,16);
CREATE INDEX idx_cusvcc_cust_acct ON cbsdbap1.cusvcc(cust_acct_no, code);

之后查询直接用t.cust_acct_no = cm.cust_acct_no,减少函数运算开销。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:57:52