
当单表数据量逼近甚至超过数据库物理内存时,传统优化手段开始失效:索引救不了全表扫描,查询优化器也无能为力。
分区表的核心思路极其朴素:把一张逻辑上的大表,按规则切成多张物理上的小表。查询时,优化器自动排除无关分区——这叫"分区裁剪"(Partition Pruning)。实测数据显示,按月分区后,时间范围查询从 15 秒降到 0.3 秒,不是夸张,是常规操作。
PostgreSQL 10 引入的声明式分区是官方主推方案,语法简洁、管理方便,彻底取代了早期繁琐的继承式分区。
策略 | 适用场景 | 语法 |
|---|---|---|
Range(范围) | 时间序列、ID 范围,最常用 | PARTITION BY RANGE (date) |
List(列表) | 离散枚举值,如地区、状态 | PARTITION BY LIST (region) |
Hash(哈希) | 无明显规律,需均匀分布 | PARTITION BY HASH (id) |
选型铁律:分区键必须是高频查询的 WHERE 条件列。 选错了,优化器无法裁剪,反而比不分区更慢。
以电商订单表为例,数据量 5 亿+,按 order_date 范围分区。
第一步:创建父表(不存数据)
sqlCREATE TABLE orders (
order_id BIGSERIAL,
customer_id INT NOT NULL,
order_date DATE NOT NULL,
amount DECIMAL(12,2) NOT NULL,
PRIMARY KEY (order_id, order_date) -- 必须包含分区键
) PARTITION BY RANGE (order_date);⚠️ 坑点:主键必须包含分区键。 这是 PostgreSQL 的硬性约束,因为跨分区无法保证全局唯一。
第二步:创建分区
sqlCREATE TABLE orders_202501 PARTITION OF orders
FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');
CREATE TABLE orders_202502 PARTITION OF orders
FOR VALUES FROM ('2025-02-01') TO ('2025-03-01');区间规则是左闭右开 [t1, t2),下边界包含,上边界不包含。
第三步:插入数据,自动路由
sqlINSERT INTO orders (customer_id, order_date, amount)
VALUES (1001, '2025-01-15', 299.00);
-- 自动落入 orders_202501,应用层完全无感知第四步:建索引
sql-- 全局索引,自动应用到所有分区(PG11+)
CREATE INDEX idx_orders_date ON orders (order_date);
-- 唯一索引同样必须包含分区键
CREATE UNIQUE INDEX idx_orders_customer ON orders (customer_id, order_date);操作 | 命令 | 耗时 |
|---|---|---|
加分区 | CREATE TABLE ... PARTITION OF ... | 秒级 |
删分区 | DROP TABLE 分区名 | 秒级(比 DELETE 快万倍) |
分离分区 | ALTER TABLE ... DETACH PARTITION ... | 毫秒级(PG12+ 支持 CONCURRENTLY) |
附加分区 | ALTER TABLE ... ATTACH PARTITION ... | 秒级 |
删除旧数据的正确姿势:不要 DELETE,直接 DROP PARTITION。 DELETE 产生大量死元组,VACUUM 开销巨大;DROP 分区是瞬间释放磁盘空间,零额外开销。
建议写个 cron 每月自动建下月分区:
bash#!/bin/bash
NEXT=$(date -d "+1 month" +"%Y_%m")
psql -c "CREATE TABLE orders_${NEXT} PARTITION OF orders
FOR VALUES FROM ('$(date -d "+1 month" +"%Y-%m-01")')
TO ('$(date -d "+2 months" +"%Y-%m-01")');"ANALYZE。 分区表的统计信息需要定期更新,否则优化器可能选错执行计划。DEFAULT 分区,捕获所有不匹配的数据,避免插入报错。分区表不是银弹,但它是处理海量数据最确定性的手段。核心就一句话:让查询只扫该扫的数据,让维护只动该动的分区。 选对分区键,管好分区数,你的大表就不再是负担,而是可控的资产。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。