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數據庫性能的重要工具。