表分區將大型表按邏輯劃分為多個物理分區,獨立儲存於不同表空間,核心效益:
適用數值/日期欄位,按連續區間劃分
CREATE TABLE STUDENT (
STUDENTID INTEGER NOT NULL,
STUDENTNAME VARCHAR2(20),
SCORE INTEGER
)
PARTITION BY RANGE (SCORE) (
PARTITION P1 VALUES LESS THAN (60),
PARTITION P2 VALUES LESS THAN (75),
PARTITION P3 VALUES LESS THAN (85),
PARTITION P4 VALUES LESS THAN (MAXVALUE)
);
關鍵點:MAXVALUE 接收超出所有範圍的資料,確保完整性。
依 Oracle 內部雜湊演算法分布,適合無明顯範圍特徵的欄位
CREATE TABLE DEPARTMENT (
DEPTNO INT,
DEPTNAME VARCHAR2(24)
)
PARTITION BY HASH (DEPTNO) (
PARTITION P1,
PARTITION P2
);
分區數建議為 2 的冪次(2、4、8、16)以利均勻分布。
範圍分區 + 子分區雜湊,結合兩者優勢
CREATE TABLE SALGRADE (
GRADE NUMBER,
LOSAL NUMBER,
HISAL NUMBER
)
PARTITION BY RANGE (GRADE)
SUBPARTITION BY HASH (LOSAL, HISAL) (
PARTITION P1 VALUES LESS THAN (10) (
SUBPARTITION SP1, SUBPARTITION SP2
),
PARTITION P2 VALUES LESS THAN (20) (
SUBPARTITION SP3, SUBPARTITION SP4
)
);
適用字串/離散數值,明確指定值清單
CREATE TABLE CUSTOMER (
CUSTNO INT,
CUSTNAME VARCHAR2(20),
CUSTSTATE VARCHAR2(20)
)
PARTITION BY LIST (CUSTSTATE) (
PARTITION ASIA VALUES ('中國','韓國','日本'),
PARTITION EUROPE VALUES ('英國','俄國','法國'),
PARTITION AMERICA VALUES ('美國','加拿大','墨西哥')
);
注意:未匹配值會報錯,建議加 DEFAULT 分區收納。
| 操作 | 語法範例 | 說明 |
|---|---|---|
| 新增分區 | ALTER TABLE STUDENT ADD PARTITION P5 VALUES LESS THAN (120); | 範圍/列表分區適用 |
| 刪除分區 | ALTER TABLE STUDENT DROP PARTITION P4; | 資料同步刪除,不可回滾 |
| 截斷分區 | ALTER TABLE STUDENT TRUNCATE PARTITION P5; | 保留結構,清空資料,釋放空間 |
| 合併分區 | ALTER TABLE STUDENT MERGE PARTITIONS P3,P4 INTO PARTITION P6; | 相鄰分區合併 |
| 分割分區 | ALTER TABLE STUDENT SPLIT PARTITION P4 AT (90) INTO (PARTITION P4, PARTITION P5); | 一分為二 |
| 交換分區 | ALTER TABLE STUDENT EXCHANGE PARTITION P1 WITH TABLE STAGING_TABLE; | 與非分區表交換,極速載入/歸檔 |
| 移動分區 | ALTER TABLE STUDENT MOVE PARTITION P2 TABLESPACE TS_DATA2; | 跨表空間遷移 |
PARTITION BY RANGE (DT) INTERVAL (NUMTODSINTERVAL(1,'DAY')) 自動建立新分區DBMS_STATS.GATHER_TABLE_STATS(..., GRANULARITY=>'PARTITION')-- 檢視分區裁剪效果
EXPLAIN PLAN FOR SELECT * FROM STUDENT WHERE SCORE = 80;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- 查詢分區統計
SELECT TABLE_NAME, PARTITION_NAME, NUM_ROWS, BLOCKS, LAST_ANALYZED
FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'STUDENT';