單表超百萬行性能下降不可避免,分表雖有效但改動架構成本高。MySQL 5.1 引入 Partition,在單實例內部實現數據水平切分,兼具性能與透明性。
DROP PARTITION 瞬時完成,避免 DELETE 鎖表產生碎片SUM/COUNT 可跨分區並行聚合CREATE TABLE t_range (
id INT, money INT UNSIGNED NOT NULL, dt DATETIME
) PARTITION BY RANGE (YEAR(dt)) (
PARTITION p2007 VALUES LESS THAN (2008),
PARTITION p2008 VALUES LESS THAN (2009),
PARTITION p2009 VALUES LESS THAN (2010),
PARTITION p2010 VALUES LESS THAN MAXVALUE
);
適用:時間序列、數值範圍、歸檔場景。
CREATE TABLE t_list (
a INT, b INT
) PARTITION BY LIST (b) (
PARTITION p0 VALUES IN (1,3,5,7,9),
PARTITION p1 VALUES IN (2,4,6,8,0)
);
適用:枚舉型業務鍵(地域代碼、業務類型)。
CREATE TABLE t_hash (
a INT, dt DATETIME
) PARTITION BY HASH (YEAR(dt)) PARTITIONS 4;
目標:數據均勻分佈,避免熱點。分區數建議 2 的冪次。
CREATE TABLE t_key (
a INT, dt DATETIME
) PARTITION BY KEY (dt) PARTITIONS 4;
差異:由 MySQL 內部哈希函數計算,NDB Cluster 用 MD5,其他引擎用類似 PASSWORD() 算法。支持非整數列。
PARTITION BY RANGE COLUMNS (dt, region)支持類型:所有整數、DATE/DATETIME、CHAR/VARCHAR/BINARY/VARBINARY。不支持 FLOAT/DECIMAL/BLOB/TEXT。
ALTER TABLE sale_data ADD PARTITION (PARTITION p201010 VALUES LESS THAN (201011));
ALTER TABLE sale_data DROP PARTITION p201010;
ALTER TABLE sale_data REORGANIZE PARTITION p201001,p201002,p201003,
p201004,p201005,p201006,p201007,p201008,p201009 INTO (
PARTITION p2010Q1 VALUES LESS THAN (201004),
PARTITION p2010Q2 VALUES LESS THAN (201007),
PARTITION p2010Q3 VALUES LESS THAN (201010)
);
-- 檢查是否支持分區
SHOW VARIABLES LIKE '%partition%';
-- have_partition_engine = YES
-- 查看表分區信息
SHOW CREATE TABLE t_range\G
EXPLAIN PARTITIONS SELECT * FROM t_range WHERE dt > '2008-01-01';