表格分区,指把一张数据库大的表,分散到多个小的物理存储块中。好处在于:
- 查询性能得到显著提高,特别是热点行处于同个分区中时
- 如果分区规划得好,使得查询或更新时数据大多处在同个分区中时,性能会大幅提升。因为可以利用硬盘的顺序读,而不用使用随机读取散落在各处的数据
- 批量操作更快了
在数据库系统有分区功能之前,人工进行分表已经是常见操作。数据库直接提供分区直接,则方便了使用者。
分区在表特别大时才有意义。一般来讲特别大指表的数据量超过了 DB 服务器的物理内存大小。
使用 重要
建一张大表,表示按 logdata
字段分区:
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
然后建分区:
CREATE TABLE measurement_y2006m02 PARTITION OF measurement
FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
CREATE TABLE measurement_y2006m03 PARTITION OF measurement
FOR VALUES FROM ('2006-03-01') TO ('2006-04-01');
...
这表示向 measurement
中插入数值时,会按 logdata
的值分到不同的分区去存储。如果 logdata
的值所处的 分区不存在则会报错。
对于被用来分区的字段,建一个索引来加速查询是惯常的做法:
CREATE INDEX ON measurement (logdate);
删除数据 一般
删掉老数据是常见场景。有两种方法:
- 直接 DROP 相应的表:
DROP TABLE measurement_y2006m02
。这个操作速度很快,因为不需要像没分区时去一张大表一行一行删除;但是它在删除期间仍然会给母表上一个ACCESS EXCLUSIVE
锁 - DETACH 分区(推荐):
ALTER TABLE measurement DETACH PARTITION measurement_y2006m02
。这个操作不会删除数据,速度更快,不会上锁。后续对母表的查询,则再查不到这块数据
Partition Attachment 不重要
分区表也可以先在外部创建,再 attach 到母表上。这样做的好处是,可以从外部加载数据,对数据做校验或者清理工作后,再 attach 到母表上被使用。操作示例:
CREATE TABLE measurement_y2008m02
(LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS)
TABLESPACE fasttablespace;
ALTER TABLE measurement_y2008m02 ADD CONSTRAINT y2008m02
CHECK ( logdate >= DATE '2008-02-01' AND logdate < DATE '2008-03-01' );
\copy measurement_y2008m02 from 'measurement_y2008m02'
-- possibly some other data preparation work
ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02
FOR VALUES FROM ('2008-02-01') TO ('2008-03-01' );
注意:第二步中的 CHECK 如果不做,attach 时分区表和母表都会上锁。Attach 后再把这个 check constraint 去掉即可。
其他 不重要
其他细节没有深究。有需要时再查 文档。
分区的类型
- Range Partitioning
- List Partitioning
- Hash Partitioning