---
title: 大量 union all 与 not in 条件 SQL 语句执行报错 4013-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于大量 union all 与 not in 条件 SQL 语句执行报错 4013相关的常见问题和使用技巧，帮助您快速解决大量 union all 与 not in 条件 SQL 语句执行报错 4013的难题。
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

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

划线反馈

# 大量 union all 与 not in 条件 SQL 语句执行报错 4013

更新时间：2026-08-25 08:16

适用版本： V3.2.x 内容类型：Troubleshoot  

## 问题现象

客户生产环境执行固定 SQL 报错 4013。排查发现，该 SQL 执行期间 SqlExecContext 内存异常上涨，最终触发报错。报错 SQL 较长，包含 13 个 union all，且每个 select 中都有较多 in 条件；减少 union all 数量可以规避。 | OBServer 版本 | 执行现象 | | --- | --- | | 3.2.3.3-111010012024081311 | 执行正常 14s | | 3.2.3.3-107030052023031712 | 执行报错 4013 |

## 关键诊断信息

### 触发条件

SQL 中包含大量 union all 语句（13 个以上）以及大量的 not in 条件。

### 事前巡检

检查 SQL 是否存在 union/union all 语句 + 大量 not in 条件的问题写法，问题 SQL 结构示例如下：

```sql
with now_contr as (
  select
  ....
  from
    ....
  where
    cl..... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
    and ....
),
last_contr as (
  select
  ....
  from
    ....
  where
    cl.pk_org in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
    and ....
),
now_inner_move as (
  select
    ....
  from
    ....
  where
    .... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
    and im..... not in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
),
out_person as (
  select
    ....
  from
    ....
  where
    .... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
  union
  select
    ....
  from
    ....
  where
    .... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
  union
  select
    ....
  from
    ....
  where
    .... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
  union
  select
    ....
  from
    ....
  where
    .... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
  union
  select
    ....
  from
    ....
  where
    .... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
    and .... not in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
  union
  select
    ....
  from
    ....
  where
    .... in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
    and .... not in (
      '000U',
      '000W',
      '000X',
      '000Y',
      '000Z',
      '0010',
      '0011',
      '0012',
      '0013',
      '0821'
    )
)
....

```

### 事后诊断

在 observer.log 中检索关键词 `failed to extract query range`：

```bash
grep 'failed to extract query range' observer.log

```

若返回结果中包含 `ret=-4013`，且 SQL 为大量 union/union all 语句 + 大量 not in 条件的形式，则命中此问题。 日志关键记录示例如下（已省略线程号、TraceID 等内部标识）：

```plain
[2025-03-19 12:44:17.727301] WARN  alloc ... [OOPS] alloc failed reason: tenant memory has reached the upper limit(tenant_id: 1004, tenant_hold: 68719476736, tenant_limit: 68719476736, alloc_size: 2097152)
[2025-03-19 12:44:17.727309] WARN  alloc ... oops, alloc failed, tenant_id=1004, ctx_id=5, ctx_name=SQL_EXEC_CTX_ID, ctx_hold=61027123200, tenant_hold=68719476736, tenant_limit=68719476736
[2025-03-19 12:44:17.727357] ERROR [SQL.REWRITE] ... alloc ObKeyPart failed(ret=-4013)
[2025-03-19 12:44:38.219854] WARN  [SQL.JO] ... failed to extract query range(ret=-4013, index_id=1103909674353920)

```

## 问题原因

该问题由 CTE 优化引入：CTE 优化会为复杂查询生成复杂的索引条件，生成和提取这些条件需要消耗大量内存；在未启用 IN 条件优化的 OBServer 版本上，SQL 执行期间内存持续膨胀，最终触发 4013（No memory or reach tenant memory limit）报错。

## 问题的风险及影响

执行含大量 union all 和 not in 条件的 SQL 时报错 4013（No memory or reach tenant memory limit），导致 SQL 执行失败，影响业务查询正常运行。

## 影响租户

| sys | MySQL | Oracle |
| --- | --- | --- |
| YES | YES | YES |

## 影响版本

| 影响版本 | 开始版本 | 修复的 BP 版本 | （区间内）修复的 Hotfix 版本 |
| --- | --- | --- | --- |
| 3.2.3.3（BP7、BP8） | 3.2.3.3-107030052023031712 | 3.2.3.3-111010012024081311 | |

## 解决方法

1. OBServer 3.2.3 BP0~BP7：该版本区间没有 `_xsolapi_generate_with_clause` 配置项，可在相关 SQL 的 select 后添加 `/*+inline*/` Hint，控制 CTE 抽取及展开，避免 CTE 抽取导致的内存膨胀。
 2. OBServer 3.2.3 BP8~BP10：关闭 CTE 抽取优化，避免抽取复杂索引条件的 query range 消耗大量内存。执行以下命令：

   ```sql
   alter system set "_xsolapi_generate_with_clause" = 0;

   ```

## 规避方式

1. OBServer 3.2.3 BP0~BP7：可在相关 SQL 的 select 后添加 `/*+inline*/` Hint，控制 CTE 抽取及展开，避免 CTE 抽取导致的内存膨胀。
 2. OBServer 3.2.3 BP8~BP10：执行 `alter system set "_xsolapi_generate_with_clause" = 0;` 关闭 CTE 抽取优化。

Previous

[单条 SQL 内存使用超限和写临时文件超限报错分析方法](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000006897661)

Next

[添加列后，查询语句包含新加列时默认计划不优](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000006868975) ![有帮助](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) 咨询热线
