首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> Oracle 資料庫 >> Oracle 資料庫基礎

Oracle 海量資料遷移實戰:建表即查詢 (CTAS) 與直寫插入 (APPEND Hint) 兩大極速方案深度對比

     編輯:Oracle 資料庫基礎

面對 **80MB 以上** (實務常達 GB/TB 級) 的大量資料移動 —— 表空間調整、歸檔、跨 Schema 複製、測試環境構建 —— 傳統 `INSERT ... SELECT` 配合 COMMIT 速度極慢、產生海量 Redo/Undo、易導致 UNDO 表空間暴增。本文深度解析 **CTAS (Create Table As Select)** 與 **`INSERT /*+ APPEND */`** 兩大**直寫資料檔、繞過 Buffer Cache/Redo** 的極速方案,含適用場景、鎖行為、索引/約束處理與生產級腳本模板。

核心原理:Direct Path Load (直接路徑載入)

兩種方案本質相同:**繞過 SGA Buffer Cache、不產生 Redo/Undo (NOLOGGING)、直接在資料檔高水位線 (HWM) 以上格式化新區塊 (Extent) 寫入**。

機制傳統 INSERTCTAS / APPEND
路徑Conventional Path (Buffer Cache → DBWR)Direct Path (PGA → Data File)
Redo 產生完整 Redo (含 Undo)**極少** (僅字典變更、空間分配),NOLOGGING 時幾乎為零
Undo 產生大量**幾乎無**
鎖類型Row Exclusive (RX) 行級鎖**Exclusive (X) 表級鎖 (TM Lock Mode 6)**
並發影響低 (行級鎖)**高** (獨佔表,DML 會排隊/阻塞)
索引維護同步維護**不維護** (新表無索引;APPEND 使索引 UNUSABLE)

方案一:CTAS (Create Table As Select) —— 遷移建新表首選

語法模板


CREATE TABLE target_schema.target_table
TABLESPACE target_tbs
NOLOGGING                                     -- 關鍵:最小化 Redo
PCTFREE 10 PCTUSED 60
STORAGE (INITIAL 5M NEXT 5M MINEXTENTS 1 MAXEXTENTS UNLIMITED PCTINCREASE 0)
AS
SELECT * FROM source_schema.source_table
WHERE <過濾條件>;                              -- 分區剪枝、業務篩選

自動繼承 / 不繼承清單

物件是否繼承後續處理
欄位定義、資料類型、NOT NULL 約束✅ 是無
Primary Key、Unique、Foreign Key、Check 約束❌ 否**必須手動重建**
預設值 (DEFAULT)❌ 否手動 `ALTER TABLE ... MODIFY ... DEFAULT ...`
索引❌ 否**建表後平行建立** (`CREATE INDEX ... PARALLEL n`)
分區定義❌ 否需在 CTAS 中指定 `PARTITION BY ...` 或事後 `EXCHANGE PARTITION`
Grant/權限❌ 否手動授權

生產級腳本:分批 CTAS + 索引平行建立 + 權限同步


-- 1. 建表 (大表建議加 PARALLEL)
CREATE TABLE tgt_schema.big_table 
TABLESPACE big_data_tbs NOLOGGING PARALLEL 8
AS SELECT * FROM src_schema.big_table WHERE created_dt >= DATE '2023-01-01';

-- 2. 立即收集統計資訊 (關鍵:CTAS 後無統計資訊)
EXEC DBMS_STATS.GATHER_TABLE_STATS('TGT_SCHEMA', 'BIG_TABLE', DEGREE=>8);

-- 3. 平行建立索引 (排序在 PGA 完成,極快)
CREATE INDEX tgt_schema.idx_big_table_col1 ON tgt_schema.big_table(col1) 
TABLESPACE idx_tbs NOLOGGING PARALLEL 8;
-- 重建所有索引腳本
BEGIN
  FOR r IN (SELECT index_name FROM user_indexes WHERE table_name = 'BIG_TABLE') LOOP
    EXECUTE IMMEDIATE 'ALTER INDEX '||r.index_name||' REBUILD PARALLEL 8 NOLOGGING';
  END LOOP;
END;
/

-- 4. 重建約束 (PK 必須先有 Unique Index)
ALTER TABLE tgt_schema.big_table ADD CONSTRAINT pk_big_table PRIMARY KEY (id) 
USING INDEX (CREATE UNIQUE INDEX tgt_schema.pk_big_table ON tgt_schema.big_table(id) PARALLEL 8);

-- 5. 同步權限
-- 可從 ALL_TAB_PRIVS 查詢源表權限並動態生成 GRANT 腳本

方案二:INSERT /*+ APPEND */ —— 既有表追加/刷新資料首選

語法模板


-- 1. 目標表必須存在且結構相容
-- 2. 執行直寫插入
INSERT /*+ APPEND */ INTO target_schema.target_table
SELECT * FROM source_schema.source_table
WHERE <條件>;

COMMIT; -- 必須提交才能釋放獨佔鎖、使資料可見

關鍵鎖行為與並發影響

  • 執行期間持有 **TM Lock Mode 6 (Exclusive)**,阻塞該表上**所有 DML (INSERT/UPDATE/DELETE)** 甚至 `SELECT ... FOR UPDATE`。
  • `SELECT` (不加 FOR UPDATE) **不受阻塞**,但讀到的資料可能不一致 (尚未提交)。
  • **嚴禁在 OLTP 核心業務表上直接執行**,除非維護窗口或可容忍短暫寫入凍結。

索引處理:APPEND 導致索引 UNUSABLE


-- 執行 APPEND 後,目標表所有索引狀態變為 UNUSABLE
-- 必須重建
ALTER INDEX target_schema.idx_target_table_col REBUILD ONLINE PARALLEL 8;
-- 或事先標記不可用再重建 (11g+)
ALTER INDEX ... UNUSABLE; -- 避免 APPEND 期間維護開銷
INSERT /*+ APPEND */ ...;
ALTER INDEX ... REBUILD;

進階技巧:APPEND_VALUES (單行/批次直寫)


-- PL/SQL 批次處理中使用
FORALL i IN 1..v_cnt
  INSERT /*+ APPEND_VALUES */ INTO target_table VALUES v_rec(i);
-- 適用於中小批次 (千~萬行),避免單行直寫產生大量小 Extent

方案選型決策矩陣

場景推薦方案核心理由
全新建表、跨表空間/Schema 遷移CTAS一條 SQL 完成建表+載入、可指定 TABLESPACE/STORAGE/NOLOGGING、最乾淨
既有表追加歷史資料、定期歸檔INSERT /*+ APPEND */保留表結構/權限/索引定義、僅追加資料
全表替換 (Truncate + Reload)TRUNCATE + APPENDTRUNCATE 瞬間釋放空間、重設 HWM、比 DELETE 快萬倍
需保留目標表索引/約束/權限APPEND (配合索引重建)避免重建數百個 Grant/同義詞/視圖依賴
OLTP 核心表、不可阻塞寫入**禁用兩者** → 改用 RMAN 複製、GoldenGate、或分批小額 COMMIT獨佔鎖會凍結業務寫入

通用最佳實務清單

  1. NOLOGGING 雙重保險:表/索引/表空間層面皆設定 `NOLOGGING`,確保極少 Redo。
  2. PARALLEL 度設定:CPU 核心數 × 0.5 ~ 1.0 (如 16 核 → PARALLEL 8),監控 `V$PX_SESSION` 避免過度並行。
  3. 統計資訊即時收集:CTAS/APPEND 後 **必須** `DBMS_STATS.GATHER_TABLE_STATS`,否則 CBO 走全表掃描災難。
  4. 空間預估與監控:目標表空間預留 1.5× 源資料大小,監控 `DBA_FREE_SPACE` 避免寫滿中斷。
  5. 驗證機制:行數比對 (`COUNT(*)`)、抽樣比對關鍵欄位 Checksum (`DBMS_SQLHASH`)、約束啟用驗證 (`ENABLE VALIDATE`)。
  6. 備份配合:NOLOGGING 操作後 **必須立即進行 Level 0/1 備份**,否則媒介恢復時該段資料不可恢復 (Standby 同步會報錯)。

總結

**CTAS** 是「建新表遷移」的王者,**INSERT /*+ APPEND */** 是「既有表追加」的利器。兩者核心都是 **Direct Path + NOLOGGING**,犧牲並發 (獨佔鎖) 換取極致載入速度與最小 Redo。**生產環境鐵律:維護窗口執行、索引事後平行重建、統計資訊即時收集、備份即時跟進。** 掌握這套組合拳,TB 級資料遷移也能在小時級完成。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved