---
title: SELECT 投影列中关联子查询的 SQL 性能问题-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 SELECT 投影列中关联子查询的 SQL 性能问题相关的常见问题和使用技巧，帮助您快速解决 SELECT 投影列中关联子查询的 SQL 性能问题的难题。
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# SELECT 投影列中关联子查询的 SQL 性能问题

更新时间：2026-05-14 09:21

适用版本： V2.1.x、V2.2.x、V3.1.x、V3.2.x、V4.0.x、V4.1.x、V4.2.x 内容类型：Troubleshoot  

## 适用版本

OceanBase 数据库所有版本。

## 问题现象

SQL 的 SELECT 列表中包含 IN 子查询（标量子查询），SQL 执行超时，存在性能问题。如果把 SELECT 投影中的 IN 查询去掉，SQL 仅需要 18 秒。

- 问题 SQL 如下：

  ```shell
  SELECT CASE
          WHEN a.cus_ac IN (SELECT d2.cus_ac FROM ods. table_d d2) THEN d1.rcv_br
          ELSE a.rcv_br
      END AS rcv_br
  FROM   ods. table_a a
      LEFT JOIN rts. table_b b
              ON Substr(20350623, 5, 2) = b.month
      LEFT JOIN ods. table_c c
              ON a.cus_ac = c. cus_ac
      LEFT JOIN ods.table_d d1
              ON a. cus_ac = d1.cus_ac
      LEFT JOIN ods.table_e e
              ON a. cus_ac = e.cus_ac
      LEFT JOIN rts.table_f f
              ON a.aco_br = f. org_code

  ```
 - EXPLAIN 信息如下：

  ```
  ==========================================================================================
  |ID|OPERATOR                                |NAME            |EST. ROWS    |COST         |
  ------------------------------------------------------------------------------------------
  |0 |SUBPLAN FILTER                          |                |3.176721e+12 |1.270232e+15 |
  |1 | HASH RIGHT OUTER JOIN                  |                |3.176721e+12 |705654824484 |
  |2 |  TABLE SCAN                            |F               |100000       |38681        |
  |3 |  MERGE OUTER JOIN                      |                |3241218738   |729667481    |
  |4 |   MERGE OUTER JOIN                     |                |31198358     |12100047     |
  |5 |    MERGE OUTER JOIN                    |                |1199599      |5173238      |
  |6 |     NESTED-LOOP OUTER JOIN CARTESIAN   |                |1199599      |5110492      |
  |7 |      TABLE SCAN                        |A(TABLE_A_I1)   |1199599      |4671605      |
  |8 |      MATERIAL                          |                |1            |46           |
  |9 |       TABLE SCAN                       |B               |1            |46           |
  |10|     TABLE SCAN                         |E(TABLE_E_I1)   |17           |46           |
  |11|    SORT                                |                |2653         |5880         |
  |12|     TABLE SCAN                         |D1              |2653         |1027         |
  |13|   TABLE SCAN                           |C(TABLE_C_I1)   |10599        |4100         |
  |14| TABLE SCAN                             |D2(TABLE_D_I1)  |2653         |1027         |
  ==========================================================================================

  ```

## 问题原因

EXPLAIN 信息显示该 SQL 执行中的主要性能瓶颈在：

- 算子 0: SUBPLAN FILTER。
     - 该算子需要用算子 1 的结果，3.17672le+12 条记录，逐一与 subplan（14 号算子） 进行匹配。
     - 该算子的代价估算为：1.270232e+15 - 705654824484 = 1.269526E+15。
 - 算子 1: HASH RIGHT OUTER JOIN。
     - 该算子需要用算子 3 的结果，3241218738 条记录，逐一与 算子 2 的 hash 结果，100000 条记录，进行 join。
     - 该算子的代价估算为：705654824484 - 38681 - 729667481 =7.049251E+11。

最主要的性能瓶颈则是算子 0：SUBPLAN FILTER。SUBPLAN FILTER 的实现类似于 NLJ，当主查询的结果集很大时，需要对 SUBPLAN 中重复执行太多次的 TABLE SCAN（走索引 TABLE_D_I1），效率非常低。

## 解决方法

改写 SQL，将标量子查询改写为 LEFT JOIN，让优化器根据代价估算选择更好的 Join 方式。需要注意的是，要保证改写后字段 table_d.cus_ac 的唯一性，如果该字段不是唯一键，则需要使用 DISTINCT 来去重。

- 改写后的 SQL 如下：

  ```shell
  SELECT CASE
          WHEN d2.cus_ac IS NULL THEN a_f.arcvbr
          ELSE a_f.brevbr
      END AS rcv_br
  FROM   (SELECT a. cus_ac,
          a.rcv_br  AS arcvbr,
          d1. rcv_br AS brevbr
          FROM   ods. table_a a
          LEFT JOIN rts. table_b b
          ON Substr(20350623, 5, 2) = b.month
          LEFT JOIN ods. table_c c
          ON a.cus_ac = c. cus_ac
          LEFT JOIN ods.table_d d1
          ON a. cus_ac = d1.cus_ac
          LEFT JOIN ods.table_e e
          ON a. cus_ac = e.cus_ac
          LEFT JOIN rts.table_f f
          ON a.aco_br = f. org_code) a_f
      LEFT JOIN （select distinct cus_ac from ods. table_d） d2
              ON a_f.cus_ac = d2. cus_ac

  ```
 - 改写后的 EXPLAIN 信息未搜集。根据客户描述，改写后，优化器使用 Hash Join 把主查询与 d2 进行关联，执行效率提升万倍。

上一篇

[Oracle 租户下包含 rownum 时查看执行计划中相关的信息](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000217880)

下一篇

[如何导出 OUTLINE 实现稳定的执行计划](https://www.oceanbase.com/knowledge-base/oceanbase-database-20000001041) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
