系統講解 MySQL 5.1+ 分區功能:RANGE/LIST/HASH/KEY/子分區/Columns 分區創建語法、管理操作、性能優勢、與分表區別聯繫。
將一張大表的數據/索引文件(.MYD/.MYI)按規則物理拆分為多個小塊(分區),查詢時僅掃描相關分區(**分區裁剪**),突破單文件大小限制,支援跨磁盤分佈。
CREATE TABLE user ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), sex TINYINT ) ENGINE=MyISAM PARTITION BY RANGE (id) ( PARTITION p0 VALUES LESS THAN (3), PARTITION p1 VALUES LESS THAN (6), PARTITION p2 VALUES LESS THAN (9), PARTITION p3 VALUES LESS THAN (12), PARTITION p4 VALUES LESS THAN MAXVALUE );
優勢: 歷史數據歸檔、按時間/ID 範圍查詢極快。
CREATE TABLE list_part ( id INT NOT NULL, province_id TINYINT, name VARCHAR(50), sex TINYINT ) ENGINE=InnoDB PARTITION BY LIST (province_id) ( PARTITION p0 VALUES IN (1,2,3,4,5,6,7,8), PARTITION p1 VALUES IN (9,10,11,12,16,21), PARTITION p2 VALUES IN (13,14,15,19), PARTITION p3 VALUES IN (17,18,20,22,23,24) );
限制: 分區鍵必須包含在主鍵中(若有主鍵),否則報錯 ERROR 1503。
CREATE TABLE hash_part ( id INT AUTO_INCREMENT PRIMARY KEY, comment VARCHAR(1000), ip VARCHAR(25) ) ENGINE=InnoDB PARTITION BY HASH(id) PARTITIONS 3;
用途: 均勻分佈熱點數據,無明確範圍邏輯時。
CREATE TABLE key_part ( news_id INT, content VARCHAR(1000), u_id VARCHAR(25), create_time DATE ) ENGINE=InnoDB PARTITION BY LINEAR HASH(YEAR(create_time)) PARTITIONS 3;
由 MySQL 內部哈希函數計算,支援非整數列。
CREATE TABLE sub_part ( news_id INT, content VARCHAR(1000), u_id INT, create_time DATE ) ENGINE=InnoDB PARTITION BY RANGE(YEAR(create_time)) SUBPARTITION BY HASH(TO_DAYS(create_time)) ( PARTITION p0 VALUES LESS THAN (1990) (SUBPARTITION s0, s1, s2), PARTITION p1 VALUES LESS THAN (2000) (SUBPARTITION s3, s4, good), PARTITION p2 VALUES LESS THAN MAXVALUE (SUBPARTITION tank0, tank1, tank3) );
規則: 所有分區子分區數相同;同分區內子分區名唯一,跨分區可重名(5.1.50 有 bug 禁止重名)。
支援整數、日期、字符串直接分區,無需轉換函數。
CREATE TABLE daily_log (
id INT, sid CHAR(36), sname CHAR(20), date DATETIME,
PRIMARY KEY (id, date)
) ENGINE=InnoDB
PARTITION BY RANGE COLUMNS(date) (
PARTITION p1 VALUES LESS THAN ('2000-01-02'),
PARTITION p2 VALUES LESS THAN ('2000-01-03'),
...
PARTITION p367 VALUES LESS THAN (MAXVALUE)
);
| 操作 | RANGE/LIST | HASH/KEY |
|---|---|---|
| 刪除分區 | ALTER TABLE t DROP PARTITION p0; | 不支援直接刪除,需 COALESCE PARTITION n 減少分區數 |
| 新增分區 | ALTER TABLE t ADD PARTITION (PARTITION p4 VALUES LESS THAN MAXVALUE); | ALTER TABLE t ADD PARTITION PARTITIONS 4;(重新分佈) |
| 重組分區 | ALTER TABLE t REORGANIZE PARTITION p0,p1 INTO (PARTITION p0 VALUES LESS THAN MAXVALUE); | 不支援 REORGANIZE |
| 優點 | 缺點/限制 |
|---|---|
| 跨磁盤存儲突破單盤容量 | 分區鍵必須為主鍵一部分(若有主鍵) |
| 分區裁剪大幅減少掃描行 | 所有分區共用表鎖/MDL 鎖,DDL 仍阻塞 |
| 大數據並行掃描(未來版本) | 外鍵不支援分區表 |
| 歷史數據快速歸檔(DROP PARTITION 秒級) | 最大 8192 個分區(5.6+) |
| 索引維護更輕量(分區級) | 查詢未命中分區鍵時全表掃描反而更慢 |
| 維度 | 分表 | 分區 |
|---|---|---|
| 物理實現 | 真正拆分為多張獨立表(各自 .frm/.MYD/.MYI) | 邏輯上一張表,物理文件按分區切割(多 .MYD/.MYI,單 .frm + .par) |
| 數據操作 | 應用/中間件路由到具體子表 | SQL 自動路由,對應用透明 |
| 性能提升點 | 並發能力、單表索引體積、磁盤 IO 分佈 | 分區裁剪、索引維護、跨磁盤並行 IO |
| 實現難度 | Merge 引擎簡單,其他方案複雜(需中間件/應用改造) | 建表時聲明,對應用透明,相對簡單 |
聯繫: 可結合使用——大表先分表(按業務維度),單表再分區(按時間維度),雙重優化。