全部產品
Search
文件中心

PolarDB:ALTER TABLE…SPLIT PARTITION

更新時間:Oct 24, 2025

ALTER TABLE ... SPLIT PARTITION 用於將一個範圍(RANGE)或列表(LIST)分區拆分為兩個新分區,此操作涉及資料重組且無法復原,執行前需規劃新分區邊界與名稱並確認資料已備份。

文法介紹

-- 拆分 RANGE 分區
ALTER TABLE table_name SPLIT PARTITION partition_name
  AT (range_part_value)
  INTO 
  (
    PARTITION new_part1 
      [TABLESPACE tablespace_name],
    PARTITION new_part2 
      [TABLESPACE tablespace_name]
  ); 

-- 拆分 LIST 分區
ALTER TABLE table_name SPLIT PARTITION partition_name
  VALUES (value[, value]...) 
  INTO 
  (
    PARTITION new_part1 
      [TABLESPACE tablespace_name],
    PARTITION new_part2 
      [TABLESPACE tablespace_name]
  );

參數說明

參數名稱

參數要求

參數說明

參數樣本

table_name

必填

目標資料分割表的名稱。

log_archives

partition_name

必填

要拆分的現有分區的名稱。

p_2022

AT (range_part_value)

用於 RANGE 分區拆分

定義 RANGE 分區的拆分點。該值將成為第二個新分區的下邊界。

AT (TO_DATE('2022-07-01', 'YYYY-MM-DD'))

VALUES (value[, value]...)

用於 LIST 分區拆分

定義 LIST 分區拆分時,分配給第一個新分區的值列表。

VALUES ('China', 'Singapore')

INTO (...)

必填

指定兩個新分區的名稱和可選的資料表空間。new_part1 包含拆分點之前的資料,new_part2 包含拆分點之後的資料。

INTO (PARTITION p_h1, PARTITION p_h2)

TABLESPACE tablespace_name

可選
預設值:表的預設資料表空間

為新分區指定儲存資料表空間。可為兩個新分區指定不同或相同的資料表空間。

TABLESPACE tbs_archive

注意事項

  • 執行此命令的使用者需是該表的所有者,或擁有對該表的 ALTER 許可權。

  • SPLIT PARTITION 會擷取 AccessExclusiveLock(表級獨佔鎖定),阻塞該表的所有 DML 和大部分 DDL 操作。建議在業務低峰期執行,並預留足夠的時間視窗。

  • 拆分點的定義必須合法:

    • AT的值必須在被拆分RANGE分區的上下界之間;

    • VALUES的值列表必須是被拆分LIST分區值列表的子集。

使用樣本

拆分範圍(RANEG)分區

本樣本示範如何將一個年度日誌分區 p_2022 拆分為兩個半年度分區 p_2022_h1 和 p_2022_h2

環境準備

本步驟將建立一個按日誌時間範圍分區的表 log_archives,並插入跨越拆分點的資料。

-- 建立分區表
CREATE TABLE log_archives (
    log_id   INT NOT NULL,
    log_time DATE NOT NULL
)
PARTITION BY RANGE (log_time) (
    PARTITION p_2022 VALUES LESS THAN (TO_DATE('2023-01-01', 'YYYY-MM-DD'))
);

INSERT INTO log_archives VALUES (1, TO_DATE('2022-01-10', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (2, TO_DATE('2022-02-15', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (3, TO_DATE('2022-03-20', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (4, TO_DATE('2022-05-05', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (5, TO_DATE('2022-06-25', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (6, TO_DATE('2022-07-15', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (7, TO_DATE('2022-08-01', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (8, TO_DATE('2022-10-30', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (9, TO_DATE('2022-11-11', 'YYYY-MM-DD'));
INSERT INTO log_archives VALUES (10, TO_DATE('2022-12-24', 'YYYY-MM-DD'));

前置檢查

在執行拆分操作前,確認資料已備份,並檢查原始分區的存在性。

-- 重要:執行拆分操作前,請確保已對相關資料進行備份。
SELECT PARTITION_NAME FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'LOG_ARCHIVES';

執行操作

以 2022-07-01 為拆分點,執行 SPLIT PARTITION 命令。

ALTER TABLE log_archives SPLIT PARTITION p_2022 
AT (TO_DATE('2022-07-01', 'YYYY-MM-DD'))
INTO (PARTITION p_2022_h1, PARTITION p_2022_h2);

結果驗證

驗證原始分區被替換為兩個新分區,且資料已正確分布。

-- 結構驗證:確認新分區已建立,舊分區已消失
SELECT PARTITION_NAME FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'LOG_ARCHIVES';
-- 查詢結果應包含 p_2022_h1, p_2022_h2,不包含 p_2022

-- 資料驗證:確認資料按拆分點分布
SELECT COUNT(*) FROM log_archives PARTITION (p_2022_h1); -- 結果應為 5
SELECT COUNT(*) FROM log_archives PARTITION (p_2022_h2); -- 結果應為 5

拆分列表(LIST)分區

本樣本示範如何將一個包含多個省/地區的亞洲銷售分區 p_asia,拆分為一個單獨的中國分區 p_china 和一個包含其他亞洲省/地區的分區 p_asia_others

環境準備

本步驟將建立一個按銷售地區列表分區的表 sales_by_region

-- 建立分區表
CREATE TABLE sales_by_region (
    sale_id INT,
    country VARCHAR2(20)
)
PARTITION BY LIST (country) (
    PARTITION p_asia VALUES ('China', 'Japan', 'Korea', 'Singapore')
);
INSERT INTO sales_by_region VALUES (101, 'China');
INSERT INTO sales_by_region VALUES (102, 'China');
INSERT INTO sales_by_region VALUES (201, 'Japan');
INSERT INTO sales_by_region VALUES (301, 'Korea');
INSERT INTO sales_by_region VALUES (401, 'Singapore');

前置檢查

檢查待拆分的 p_asia 分區是否存在及其資料分布。

SELECT PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'SALES_BY_REGION';
SELECT country, COUNT(*) FROM sales_by_region GROUP BY country;

執行操作

使用 VALUES 子句,將 p_asia 分區中值為 'China' 的資料拆分到新分區 p_china

ALTER TABLE sales_by_region SPLIT PARTITION p_asia
VALUES ('China')
INTO (PARTITION p_china, PARTITION p_asia_others);

結果驗證

驗證原始分區被替換為兩個新分區,它們的值列表已正確分配,並且資料也隨之遷移。

-- 結構驗證:確認新分區已建立及其值列表
SELECT PARTITION_NAME, HIGH_VALUE FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = 'SALES_BY_REGION';
-- 查詢結果應包含:
-- P_CHINA, 'China'
-- P_ASIA_OTHERS, 'Japan', 'Korea', 'Singapore'

-- 資料驗證:確認資料已按新分區分布
SELECT COUNT(*) FROM sales_by_region PARTITION (p_china);       -- 結果應為 2
SELECT COUNT(*) FROM sales_by_region PARTITION (p_asia_others); -- 結果應為 3

常見問題

Q1: 執行時報錯 ORA-14080: partition cannot be split
這通常是因為您定義的拆分點無效。對於 RANGE 分區,AT 的值必須在分區上下界之間;對於 LIST 分區,VALUES 的值列表必須是被拆分分區值列表的子集(非空且非全部)。

Q2: 執行時報錯 ORA-14078: partition name is already in use
這是因為您在 INTO 子句中指定的新分區名稱已經被該表中的其他分區使用,需要更換一個在表內唯一的名稱。

Q3: SPLIT PARTITION 操作執行緩慢是什麼原因?
此操作涉及物理資料的重組和拷貝,其執行時間與分區資料量成正比,會產生大量I/O。這是一個資源密集型操作,建議在業務低峰期執行。

相關語句