什麼是 SQL*Plus COPY 命令?
COPY 是 SQL*Plus 內置命令(非 SQL 語句),通過 SQL*Net 在同一或不同實例的表之間直接傳輸數據,不產生 Undo、Redo 極少,適合大批量跨庫/跨 Schema 複製。
語法詳解
COPY {FROM db | TO db | FROM db TO db}
{APPEND | CREATE | INSERT | REPLACE}
dest_table [(col, col, ...)]
USING query;
| 子句 | 說明 |
| FROM/TO db | 格式 user/pass@sid;同一 Schema 可省略一方 |
| APPEND | 追加到現有表;表不存在則自動建表(等同 CREATE) |
| CREATE | 建表並導入;表已存在報錯 |
| INSERT | 插入現有表;表不存在報錯 |
| REPLACE | 截斷目標表並重導;表不存在自動建表 |
| USING query | 源數據查詢,可跨表 JOIN、過濾 |
實戰場景示例
1. 同實例同 Schema 複製
COPY FROM scott/tiger@orcl CREATE dept_bak USING SELECT * FROM dept;
-- 或省略 TO
COPY FROM scott/tiger@orcl TO scott/tiger@orcl CREATE dept_bak USING SELECT * FROM dept;
2. 同實例不同 Schema
COPY FROM scott/tiger@orcl TO hr/hr@orcl CREATE employees USING SELECT * FROM emp;
-- USING 查詢無需加 schema 前綴
3. 跨實例遷移
CONN sys/oracle@prod AS SYSDBA
COPY FROM scott/tiger@prod TO dw/dw@dwdb REPLACE fact_sales
USING SELECT * FROM sales WHERE sale_date >= DATE '2023-01-01';
性能實測對比(508 萬行,504 MB)
| 方案 | 耗時(秒) | Undo(MB) | Redo(MB) | 評價 |
| COPY COMMAND | 520 | 0 | 592 | 適合追加、跨庫、不想產生 Undo |
| INSERT /*+ APPEND */ SELECT | 632 | 345 | 1720 | 產生大量 Undo/Redo,I/O 壓力大 |
| CREATE TABLE AS SELECT (CTAS) | 245 | 0 | 515 | 最快、最少日志,但目標表必須不存在 |
最佳實踐決策樹
- 目標表不存在 → CTAS 最優。
- 目標表存在需追加/覆蓋、跨實例/跨 Schema → COPY 命令優於 INSERT(無 Undo、Redo 少、併發影響小)。
- 小數據量(<10 萬行)、同實例同 Schema →
INSERT /*+ APPEND */ SELECT 簡單易維護。
- 極大表(TB 級)建議使用 Data Pump (
expdp/impdp) 或 GoldenGate/CDC 增量同步。
常見坑與避雷指南
- 長字符串截斷:COPY 預設
LONG 限制 80 字節,需 SET LONG 2000000000。
- 提交頻率:COPY 內部按
ARRAYSIZE 批次提交,調大 SET ARRAYSIZE 5000 減少網絡往返。
- 字符集不一致:跨庫時確保 NLS_LANG 一致,否則中文亂碼。
- 權限:需目標表 INSERT/CREATE 權限,源表 SELECT 權限。