Oracle 的 MOVE 操作是否重建表?
Oracle 的 MOVE 操作是否重建表?
Oracle 的 ALTER TABLE ... MOVE
操作实质上是重建表的物理存储结构,但保留表的逻辑定义不变。
MOVE 操作的本质
-
物理重建:
- 创建新的数据段(物理存储结构)
- 将原表数据按顺序重新插入到新段中
- 删除原数据段
- 更新数据字典指向新段
-
逻辑不变:
- 表名、列定义、约束等逻辑结构保持不变
- 表的对象ID(OBJECT_ID)会发生变化
- 依赖对象(如视图、同义词)不受影响
重建的具体表现
- 数据重组:
-- 执行前数据块状态 SELECT extent_id, block_id, blocks FROM dba_extents WHERE segment_name = 'YOUR_TABLE';-- 执行MOVE ALTER TABLE your_table MOVE;-- 执行后数据块状态(完全改变)
输出示例:
SQL> SELECT extent_id, block_id, blocks FROM dba_extents WHERE segment_name = 'T1' and OWNER='TEST';EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ----------0 2496 81 4696 82 4704 83 4712 84 4720 85 4728 86 6016 87 6024 88 6032 89 6040 810 6048 811 6056 812 6064 813 6072 814 6080 815 6088 816 6272 12817 6400 12818 6528 12819 6656 12820 6784 12821 6912 12822 7040 12823 7168 12824 7296 12825 7424 12826 7552 12827 rows selected.SQL> ALTER TABLE t1 MOVE;Table altered.SQL> SELECT extent_id, block_id, blocks FROM dba_extents WHERE segment_name = 'T1' and OWNER='TEST';EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ----------0 10080 81 10088 82 10096 83 10104 84 10240 85 10248 86 10256 87 10264 88 10272 89 10280 810 10288 811 10296 812 10304 813 10312 814 10320 815 10328 816 10368 12817 10496 12818 10624 12819 10752 12820 10880 12821 11008 12822 11136 12823 14336 12824 14464 12825 14592 12826 14720 12827 rows selected.
- DATA_OBJECT_ID变化:
-- 执行前
select object_id,data_object_id,object_name,to_char(created,‘yyyy-mm-dd hh24:mi:ss’) created from dba_objects where object_name = ‘T1’ and owner=‘TEST’ ;
– 执行后(新DATA_OBJECT_ID)
输出示例:```sql
SQL> select object_id,data_object_id ,object_name,to_char(created,'yyyy-mm-dd hh24:mi:ss') created from dba_objects where object_name = 'T1' and owner='TEST' ;OBJECT_ID DATA_OBJECT_ID OBJECT_NAME CREATED
---------- -------------- --------------- -------------------75061 75870 T1 2025-02-04 23:15:05SQL> ALTER TABLE t1 MOVE;Table altered.SQL> select object_id,data_object_id ,object_name,to_char(created,'yyyy-mm-dd hh24:mi:ss') created from dba_objects where object_name = 'T1' and owner='TEST' ;OBJECT_ID DATA_OBJECT_ID OBJECT_NAME CREATED
---------- -------------- --------------- -------------------75061 75871 T1 2025-02-04 23:15:05
- ROWID变化:
- 所有行的ROWID都会改变
- 基于ROWID的应用程序需要调整
与真正"重建表"的区别
特性 | MOVE操作 | 完全重建表(CREATE AS SELECT) |
---|---|---|
表定义 | 保留所有属性 | 需要手动重建约束、触发器等 |
对象依赖关系 | 自动保持 | 需要手动重建 |
权限 | 保留原有权限 | 需要重新授权 |
执行速度 | 较快 | 较慢 |
高水位线重置 | 完全重置 | 完全重置 |
索引状态 | 需要重建 | 需要重建 |
需要特别注意的影响
-
索引处理:
-- MOVE后必须重建索引 ALTER INDEX your_index REBUILD;
-
依赖对象:
- 物化视图日志会被清除
- 基于ROWID的物化视图需要刷新
- 某些类型的约束可能需要重新验证
-
在线操作限制:
-- 12C开始支持有限制的在线MOVE ALTER TABLE your_table MOVE ONLINE; -- 但仍有部分锁限制,可能阻塞DML
何时应该使用MOVE
-
典型场景:
- 表碎片化严重(超过30%空闲空间)
- 需要迁移到其他表空间
- 需要改变存储参数(如压缩)
- 高水位线远高于实际数据位置
-
替代方案比较:
- 对于小型表:
CREATE TABLE new_table AS SELECT * FROM old_table
- 对于最小化停机:
DBMS_REDEFINITION
在线重定义 - 对于部分优化:
SHRINK SPACE
(不改变ROWID)
- 对于小型表:
MOVE操作是Oracle提供的一种高效的"表重建"机制,它在保持逻辑结构不变的前提下,完全重建表的物理存储结构,是维护Oracle数据库性能的重要工具。