大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 56 天,也是我第 118 次进行这种操作。
今天我温习了该专栏里一篇叫《要不要使用分区表?》的文章。
关键词总结:分区表是什么?(分区表的组织形式)、分区表的引擎层行为(分区表和手工分表)、分区策略(MyIASM 分区策略、InnoDB 本地分区策略、各版本间的变动)、分区表的 server 层行为(分区表在 server 层和引擎层的访问过程)、分区表的应用场景(drop 分区和 delete 行相比)。
所学总结:
分区表是什么?
CREATE TABLE `t` (
`ftime` datetime NOT NULL,
`c` int(11) DEFAULT NULL,
KEY (`ftime`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
PARTITION BY RANGE (YEAR(ftime))
(PARTITION p_2017 VALUES LESS THAN (2017) ENGINE = InnoDB,
PARTITION p_2018 VALUES LESS THAN (2018) ENGINE = InnoDB,
PARTITION p_2019 VALUES LESS THAN (2019) ENGINE = InnoDB,
PARTITION p_others VALUES LESS THAN MAXVALUE ENGINE = InnoDB);
insert into t values('2017-4-1',1),('2018-4-1',1);
分区表的组织形式
- 对于引擎层来说,这是四张表;
- 对于 Server 层来说,这是一张表。
分区表的引擎层行为
分区表和手工分表
一个是由 server 层来决定使用哪个分区,一个是由应用层代码来决定使用哪个分表。
分区策略
MyIASM 分区策略
通用分区策略(generic partitioning),每次访问分区都由 server 层控制。通用分区策略是 MySQL 一开始支持分区表时就存在的代码,在文件管理、表管理的实现上很粗糙,因此有比较严重的性能问题。
InnoDB 本地分区策略
从 MySQL 5.7.9 开始,InnoDB 引擎引入了本地分区策略(native partitioning)。这个策略是在 InnoDB 内部自己管理打开分区的行为。
各版本间的变动
- MySQL 从 5.7.17 开始,将 MyIASM 分区表标记为即将弃用(deprecated),意思是 “从这个版本开始不建议这么使用,请使用替代方案。在将来的版本中会废弃该功能”;
- 从 MySQL 8.0 版本开始,就不允许创建 MyIASM 分区表了,只允许创建已经实现了本地分区策略的引擎。目前来看,只有 InnoDB 和 NDB 这两个引擎支持了本地分区策略。
分区表的 server 层行为
分区表在 server 层和引擎层的访问过程
- MySQL 在第一次打开分区表的时候,需要访问所有的分区;
- 在 server 层,认为这是同一张表,因此所有分区共用同一个 MDL 锁;
- 在引擎层,认为这是不同的表,因此 MDL 锁之后的执行过程,会根据分区表规则,只访问必要的分区。
分区表的应用场景
drop 分区和 delete 行相比
alter table t drop partition ...
操作是直接删除分区文件,效果跟 drop
普通表蕾丝。与使用 delete
语句删除数据相比,优势是速度快、对系统影响小。
扫描二维码关注公众号,回复:
9990649 查看本文章
末了
重新总结了一下文中提到的内容:server 层和引擎层对分区表的处理方式、MySQL 还支持 hash 分区 / list 分区等方法、分区并不是越细越好、要及时 drop 掉没有数据的历史分区、跨分区读数据慢的问题一般是数据量或使用方式造成的。