都能够提高MySQL的性能,分表能够改善高并发的性能,分区能够充分利用磁盘的I/O吞吐率。
分表和分区并不矛盾,而是可以相互配合的。对于那些访问量比较大,并且数据量比较多的表,可以采取分表和分区结合的方式(如果MERGE存储引擎的分表方式不能和分区配合的话,也可以使用其他的分表方式)。对于访问量不大,但是数据量比较多的表,可以只采取分区的方式。
分表(这里说的是MERGE引擎方式):一个对外的主表(壳子),加上N个集合表, 每个集合表都有自己的一组文件(数据MYD,索引MYI,表结构FRM)
分区:只有一个表 会有多个分区数据文件(数据MYD,索引MYI),表结构只有一个
这里重点介绍分区的一些操作:
1.创建分区表
CREATE TABLE `c_add_hours` (
`hour` datetime NOT NULL COMMENT '小时',
`add_id` varchar(50) NOT NULL DEFAULT '' COMMENT 'ID',
UNIQUE KEY `uniq_hour_ad_id` (`hour`,`add_id`) USING BTREE,
KEY `idx_ad_id` (`add_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50500 PARTITION BY RANGE COLUMNS(`hour`)
(PARTITION c_add_hours_2019_07 VALUES LESS THAN ('2019-08-01 00:00:00') ENGINE = InnoDB,
PARTITION c_add_hours_2019_08 VALUES LESS THAN ('2019-09-01 00:00:00') ENGINE = InnoDB */;
分区表的分区字段的要求和注意事项就不在这里说了;
2.增加新的分区
alter table c_add_hours add partition (PARTITION c_add_hours_2019_09 VALUES LESS THAN ('2019-10-01 00:00:00') ENGINE = InnoDB);
3.清理不需要的分区:
ALTER TABLE '表名' DROP PARTITION '分区名' ;
例如:ALTER TABLE c_add_hours DROP PARTITION c_add_hours_2019_09 ;
注意后面的分区名不能带引号
4.后期动态维护有两种办法:
A.使用 MAXVALUE
即把最后一个分区设置成 PARTITION pmax VALUES LESS THAN MAXVALUE ;
如果有数据落到了最后一个分区还可以把这个分区拆成设定规则的多个分区,比如把最后一个分区拆成三个分区,记注 最后一个分区必须还是MAXVALUE
alter table c_add_hours REORGANIZE PARTITION pmax INTO
(PARTITION p20191101 VALUES LESS THAN (1575129600),
PARTITION p20191201 VALUES LESS THAN (1577808000),
PARTITION p20200101 VALUES LESS THAN (1580486400),
PARTITION pmax VALUES LESS THAN MAXVALUE);
B.不设置 MAXVALUE
动态去维护分区,比如按月去新增分区;
这里提供一个方法:
explain partitions select * from c_add_hours where hour>= '2020-01-01 00:00:00' and hour<='2022-04-01 00:00:00';
返回数据中的:
"partitions" => "p2021_10_01,p2021_11_01,p2021_12_01,p2022_01_01,p2022_02_01,p2022_03_01,p2022_04_01"
通过查看表的分区情况,得到目前已经有的分区数据和规则,通过程序去动态给mysql表增加分区;