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

Oracle 19c中ALTER TABLE MOVE INCLUDING ROWS特定场景失效咨询

使用ALTER TABLE MOVE...INCLUDING ROWS替代DELETE时的索引异常问题

问题现象

在Oracle 19c Enterprise Edition中,使用ALTER TABLE MOVE...INCLUDING ROWS作为批量删除的高效替代方案时,出现以下不符合预期的情况:

  • 当表存在索引,且过滤条件导致移动后表为空时,走索引的查询会返回原有数据,仅强制全表扫描才能得到正确的空表结果。
  • 当过滤条件保留部分行时,UPDATE INDEXES参数能正常维护索引,查询结果符合预期。

复现步骤

-- 创建测试表及索引
create table t (
    c1 int not null
);

create index t_index on t(c1);

-- 插入测试数据
insert into t values ( 1 );
insert into t values ( 2 );

-- 执行MOVE操作,保留c1>2的行(实际无符合条件数据)
alter table t move including rows where c1 > 2 update indexes;

异常表现

执行常规查询时,查询计划显示走t_index索引全扫描,返回原有数据:

C1
1
2

对应的查询计划:

----------------------------------------------------------------------------
| Id  | Operation        | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT |         |     1 |    13 |     1   (0)| 00:00:01 |
|   1 |  INDEX FULL SCAN | T_INDEX |     1 |    13 |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------

强制走全表扫描则返回正确的空表结果:

select /*+no_index(t t_index)*/ *
from t;
---
(none)

正常场景验证

当过滤条件保留部分行时,操作及查询结果均正常:

alter table t move including rows where c1 > 1 update indexes;

select * from t;

返回结果:

C1
2

问题原因

这是Oracle 19c版本中的已知bug:当ALTER TABLE MOVE...INCLUDING ROWS操作后目标表为空时,UPDATE INDEXES参数未能正确清理索引中的旧数据,导致索引仍保留原表的记录条目。此时查询若选择走索引,就会读取到失效的索引数据,返回错误结果。

临时解决方案

  1. 执行MOVE操作后,若确认表为空,手动重建索引:
alter index t_index rebuild;
  1. 临时强制查询走全表扫描(仅用于验证,不建议长期依赖)。
  2. 升级Oracle到后续补丁集或更高版本(该问题在部分19c补丁包及21c版本中已修复)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:12:10