在 MySQL 中,分区表是将大表数据按一定规则拆分到多个物理子表中,可提升查询效率(尤其是大数据量场景)。MySQL 支持多种分区类型,以下是常见的分区创建方法:
-
分区表的所有分区必须使用相同的存储引擎。
-
主键或唯一索引必须包含分区字段(否则无法创建分区)。
按字段的范围值分区(如按时间、数值范围),适合日志、订单等有时间序列的数据。
示例:按订单日期分区
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_no VARCHAR(20) NOT NULL,
amount DECIMAL(10,2),
create_time DATE NOT NULL
)
PARTITION BY RANGE (TO_DAYS(create_time)) (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01')),
PARTITION p202303 VALUES LESS THAN (TO_DAYS('2023-04-01')),
PARTITION p_other VALUES LESS THAN MAXVALUE
);
-
按
create_time 字段的天数(TO_DAYS() 转换)分区,每个分区存储一个月的数据。
-
p_other 用于存储未匹配到前面分区的数据,避免插入数据失败。
按字段的离散值分区(如按地区、状态码),适合字段值固定且有限的场景。
示例:按地区分区
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
region_id INT NOT NULL
)
PARTITION BY LIST (region_id) (
PARTITION p_north VALUES IN (1,4,5),
PARTITION p_east VALUES IN (2,6),
PARTITION p_south VALUES IN (3)
);
-
每个分区包含指定的
region_id 列表,插入数据时根据 region_id 分配到对应分区。
按字段的哈希值均匀分配数据,适合数据分布较均匀、无明显范围特征的场景。
示例:按用户 ID 哈希分区
CREATE TABLE logs (
id INT PRIMARY KEY,
content TEXT,
user_id INT NOT NULL
)
PARTITION BY HASH (user_id)
PARTITIONS 4;
-
MySQL 会自动计算
user_id 的哈希值,将数据平均分配到 4 个分区中。
类似哈希分区,但由 MySQL 自动计算哈希值(支持字符串等更多类型)。
示例:按用户名键分区
CREATE TABLE user_login (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL
)
PARTITION BY KEY (username)
PARTITIONS 3;
SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME = 'orders';
ALTER TABLE orders
ADD PARTITION (
PARTITION p202304 VALUES LESS THAN (TO_DAYS('2023-05-01'))
);
ALTER TABLE orders DROP PARTITION p202301;
-
查询优化:查询时尽量包含分区字段(如
WHERE create_time = '2023-01-15'),MySQL 会只扫描对应分区,提升效率。
-
分区键选择:优先选择查询频繁、区分度高的字段(如时间、地区)。
-
避免过度分区:分区数量过多(如超过 1000 个)可能反而降低性能。
-
版本支持:某些分区功能(如子分区)在 MySQL 5.7+ 版本才完善,建议使用 8.0 及以上版本。
合理使用分区可以显著提升大表的查询和维护效率,尤其适合数据量百万级以上的场景。