MySQL支持数据分区,可以在对用户无感知的情况下,将对表数据的物理文件进行分区。
MySQL的分区支持Memory、MyISAM、InnoDB等存储引擎。
注意:MySQL中如果存在主键,或者唯一索引,那么分区字段必须包含这些字段。
MySQL分区的优点
1、分区后的文件可以存储在不同的分区,提高MySQL存储量
2、根据查询条件可以有选择之扫描某个分区,使用sum等聚合函数的时候可以并行检索所有分区。
3、通过一定规则的分区,可以快速删除分区内的数据,比如存储日志按月分区可以快速删除历史日志。
4、通过将分区保存在不同的硬盘之上,来提升系统的IO吞吐量。
分区相关的命令
检查MySQL版本是否支持分区
//查看表分区状态 查看 have_parttition_engine 是否为YES
SHOW VARIABLES LIKE '%parttition%';
检测SQL查询扫描了哪个分区
//检查SQL语句使用了哪个分区分区
explain partitions SQL;
MySQL的分区方式
目前MySQL支持 range、list、columns、hash、key等几种分区方式。
Range方式
Range方式的分区,可以选择指定字段根据连续的区间进行分区,比如:
小于20的分区为 p0,20-40的叫做p1 40-60的叫做p2,大于60的叫做p3,在MySQL中的表示为:
注意:Range方式定义每一个分区区间,比如按从小到大的顺序来定义。
PARTITION BY RANGE(sum) (
PARTITION p0 VALUES LESS THAN (20),
PARTITION p1 VALUES LESS THAN (40),
PARTITION p2 VALUES LESS THAN (60),
PARTITION p3 VALUES LESS THAN MAXVALUE
)
其中 sum 字段可以进行表达式运算。比如加入上面分区key为create time可以通过YEAR(createtime)来进行运算。
LIST方式
LIST方式的分区,跟Range方式类似,不同的是,LIST方式非连续区间,而是一个枚举列表的集合。
只有存在于这个枚举列表集合内的数据才可以被插入,否则不可以写入。
PARTITION BY LIST(type) (
PARTITION p0 VALUES IN (1,2,3),
PARTITION p1 VALUES IN (4,5,6),
PARTITION p2 VALUES IN (7,8,9)
)
Columns方式
Columns方式算是对Range和LIST方式的一个补充,因为Range和LIST仅仅支持整数字段分区,所以通过Columns方式可以实现非整数分区,目前支持以下类型:整型、date、datetime、char、varchar、binary、varbinary等类型。
Columns方式不可以在定义分区key的时候进行表达式运算,但是可以定义多个分区key。
PARTITION BY RANGE COLUMNS(sum, avg) (
PARTITION p0 VALUES LESS THAN (20, 5),
PARTITION p1 VALUES LESS THAN (40, 10),
PARTITION p2 VALUES LESS THAN (60, 15),
PARTITION p3 VALUES LESS THAN MAXVALUE
)
Hash分区
通过对分区key表达式取模的方式,对数据进行均匀的分区。
//id进行hash运算后分成4个分区
PARTITION BY HASH(id) PARTITIONS 4;
但是这种方式太不灵活了,扩展性非常差,不利于以后分区的扩展,所以MySQL提供另外一种线形Hash。
PARTITION BY LINEAR HASH(id) PARTTITIONS 8;
通过线形hash分区后的数据,在扩容的时候如果分区数为2的N次幂,那么计算的结果于普通hash相同,这样避免了日后扩容的数据迁移,但是也导致数据不均的问题。
Key分区
于Hash分区很类似,区别在于只支持数字,并且定义分区字段的时候不允许使用表达式,但是可以提供多个分区字段。
另外Hash分区采用MOD的方式进行计算,Key分区采用MySQL内部的Hash算法进行计算。
Key分区在存在主键或唯一索引时候可以不指定分区字段,不指定的情况会默认使用主键或唯一索引。
//根据id进行分区,并划分四个分区
PARTITION BY KEY(id) PARTITIONS 4;
复合分区
MySQL允许对Range和List分区后的每个分区再次进行Hash或Key分区操作。
PARTITION BY LIST(type)
SUBPARTITION BY KEY(id)
SUBPARTTIONS 4
(
...
)
分区字段中的NULL
分区方式 | 处理方式 |
---|---|
Hash | 作为0值 |
Key | 作为0值 |
Range | 作为最小值 |
List | 必须包含在枚举列表 |
分区的管理
Range、List
//删除某个分区
ALTER TABLE `表名` DROP PARTITION `分区名`;
//增加分区
ALTER TABLE `表名` ADD PARTITION (PARTITION p0 VALUES LESS THAN (10));
//修改分区 并自动迁移数据
ALTER TABLE `表名` REORGANIZE PARTITION INTO `一个或分区名`(更新后的分区)
Range修改分区的时候,修改多个分区必须为连续的分区不可以跳跃的修改。
List分区修改或增加的时候,不允许插入枚举列表中已经存在的值。
Hash、Key
Hash和Key两种分区类型不允许直接删除某个分区,但是可以将分区进行合并。
//修改分区个数为2 并合并数据
ALTER TABLE `表名` COALESCE PARTITION PARTITION 2;
COALESCE只可以减少分区个数不可以增加分区个数。
//增加分区个数 增加6个分区
ALTER TABLE `表名` ADD PARTITION PARTITIONS 6;
可以通过以上方式,增加指定数量的分区。
来源:oschina
链接:https://my.oschina.net/u/226106/blog/780093