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

MySQL 分區表完整指南:類型、建立、管理與效能優化實戰

     編輯:MySQL 綜合教學

MySQL 分區表完整指南:類型、建立、管理與效能優化實戰

當單表資料量達到千萬級,查詢效能明顯下降。除分表、分庫、業務拆分外,表分區是維護成本最低、代碼改動最小的方案。本文系統整理 MySQL 5.1+ 分區功能:支援檢查、五大分區類型、建立語法、子分區、索引限制與實戰建議。

如何確認資料庫支援分區

-- MySQL 5.6 之前
SHOW VARIABLES LIKE '%partition%';
-- have_partition_engine = YES 表示支援

-- MySQL 5.6 及之後
SHOW PLUGINS;
-- partition | ACTIVE | STORAGE ENGINE 表示已啟用

MySQL 僅支援水平分區(橫向拆分)

將表的不同行依規則存放於不同物理檔案,甚至不同磁碟。垂直分區(欄位拆分)不支援。

1. 建立分區表:必須在 CREATE TABLE 時指定

CREATE TABLE `T_part` (
  `f_id` INT DEFAULT NULL,
  `f_name` VARCHAR(20) DEFAULT NULL,
  PRIMARY KEY (`f_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
PARTITION BY RANGE (f_id) (
  PARTITION p0 VALUES LESS THAN (10),
  PARTITION p1 VALUES LESS THAN (20)
);
  • f_id < 10 → p0;10 ≤ f_id < 20 → p1
  • 插入 f_id ≥ 20 會報錯,需加 PARTITION p2 VALUES LESS THAN MAXVALUE 兜底

動態管理分區

-- 新增分區
ALTER TABLE T_part ADD PARTITION (PARTITION p2 VALUES LESS THAN (MAXVALUE));
-- 刪除分區(資料同步刪除!)
ALTER TABLE T_part DROP PARTITION p2;

2. 五大分區類型詳細解析

類型適用場景語法關鍵字
RANGE連續區間:時間、ID 範圍PARTITION BY RANGE(expr) + VALUES LESS THAN
LIST離散值集合:性別、狀態碼、地區代碼PARTITION BY LIST(expr) + VALUES IN (...)
HASH資料均勻分佈,無明確範圍PARTITION BY HASH(expr) + PARTITIONS N
LINEAR HASH大量資料時更優的修剪效能PARTITION BY LINEAR HASH(expr)
KEY由 MySQL 內部哈希函數計算,支援非整數欄位PARTITION BY KEY(col) + PARTITIONS N

RANGE 範例:按年份分區

CREATE TABLE range_p (
  perid INT, pername CHAR(12), monsalary DECIMAL(10,2), credate DATETIME
) PARTITION BY RANGE (YEAR(credate)) (
  PARTITION p2011 VALUES LESS THAN (2011),
  PARTITION p2012 VALUES LESS THAN (2012),
  PARTITION p2013 VALUES LESS THAN (2013),
  PARTITION p2014 VALUES LESS THAN (2014),
  PARTITION p2015 VALUES LESS THAN MAXVALUE
);

LIST 範例:按性別分區

CREATE TABLE list_p (
  perid INT, pername CHAR(12), sex INT, monsalary DECIMAL(10,2), credate DATETIME
) PARTITION BY LIST (sex) (
  PARTITION psex1 VALUES IN (1),
  PARTITION psex2 VALUES IN (2)
);

注意: LIST 僅支援整數值,字串會報錯 ERROR 1697。

HASH / KEY 範例

-- HASH
CREATE TABLE hash_p (...) PARTITION BY HASH(perid) PARTITIONS 8;
-- 或按年份哈希
CREATE TABLE hash_p (...) PARTITION BY HASH(YEAR(credate)) PARTITIONS 8;

-- KEY(MySQL 內建哈希,支援多欄位)
CREATE TABLE key_p (...) PARTITION BY KEY(perid) PARTITIONS 8;
CREATE TABLE key_p (...) PARTITION BY LINEAR KEY(perid) PARTITIONS 3;

3. 子分區:分區內再分區

CREATE TABLE T_part (
  f_id INT, f_name VARCHAR(20), PRIMARY KEY (f_id)
) PARTITION BY RANGE (f_id)
SUBPARTITION BY HASH(f_id) SUBPARTITIONS 2 (
  PARTITION p0 VALUES LESS THAN (10),
  PARTITION p1 VALUES LESS THAN (20)
);

實際產生 2×2=4 個物理分區。可進一步指定每個子分區的資料/索引目錄分離至不同磁碟:

SUBPARTITION s0 DATA DIRECTORY='/disk0/data' INDEX DIRECTORY='/disk0/idx', ...

4. 關鍵限制與避坑指南

  • 分區欄位必須包含在主鍵/唯一索引中:A PRIMARY KEY MUST INCLUDE ALL COLUMNS IN THE TABLE'S PARTITIONING FUNCTION
  • NULL 值視為 0:RANGE/LIST 分區會將 NULL 歸入最小分區,建議欄位設 NOT NULL
  • 無全域索引,僅分區索引:查詢若無分區鍵會掃描所有分區,效能劇降
  • RANGE 新增分區只能加在高端:不可插入中間區間
  • 5.5+ 支援 COLUMNS 分區:直接使用 DATE、DATETIME、CHAR、VARCHAR 等非整數型別分區

COLUMNS 分區範例(按日期直接分區)

CREATE TABLE range_p (...) 
PARTITION BY RANGE COLUMNS (credate) (
  PARTITION p20151 VALUES LESS THAN ('2015-04-01'),
  PARTITION p20152 VALUES LESS THAN ('2015-07-01'),
  PARTITION p20153 VALUES LESS THAN ('2015-10-01'),
  PARTITION p20154 VALUES LESS THAN ('2016-01-01'),
  PARTITION partlog VALUES LESS THAN MAXVALUE
);

5. 分區優化查詢原理:Partition Pruning(分區修剪)

優化器根據 WHERE 條件中的分區鍵,僅掃描相關分區。務必在 WHERE 子句包含分區鍵,否則退化為全表掃描。

6. 維護優勢

  • 歷史資料快速清理:DROP PARTITION 秒級完成,避免大量 DELETE 鎖表
  • 資料分散儲存:不同分區可掛載不同磁碟,提升 I/O 吞吐
  • 聚合函數可並行執行(SUM/COUNT 等)

總結建議

  1. 優先考慮 RANGE(時間序列)或 LIST(枚舉值)分區,業務語義最清晰
  2. HASH/KEY 適合無明確範圍但需均勻分佈的場景
  3. 分區數建議 10~100 個,過多會增加優化器開銷
  4. 嚴格測試分區修剪是否生效(EXPLAIN PARTITIONS)
  5. 官方文檔:MySQL Partitioning
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved