Phân vùng bảng (Table Partitioning) trong PostgreSQL theo thời gian: Khi nào nên bắt đầu?
Khi một bảng đơn lẻ phình to vượt quá 50 triệu dòng Khi một bảng nhật ký sự kiện auditlogs, bảng tin nhắn messages hoặc bảng thanh toán tích lũy hàng chục triệu bản ghi qua nhiều năm: - Dung lượng bả…
☰ Mục lục bài viết (4 phần) Mở / Đóng mục lục
Khi một bảng đơn lẻ phình to vượt quá 50 triệu dòng#
Khi một bảng nhật ký sự kiện (audit_logs), bảng tin nhắn (messages) hoặc bảng thanh toán tích lũy hàng chục triệu bản ghi qua nhiều năm:
- Dung lượng bảng và index vượt quá dung lượng RAM của máy chủ.
- Lệnh
VACUUMmất hàng giờ để hoàn thành và ngốn sạch I/O đĩa. - Thao tác xóa dữ liệu cũ (
DELETE FROM logs WHERE created_at < '2024-01-01') gây khóa bảng và làm phình to đĩa (Table Bloat).
Table Partitioning (Phân vùng bảng) chia nhỏ một bảng khổng lồ về mặt logic thành nhiều bảng con vật lý độc lập.
Cú pháp phân vùng Declarative Partitioning theo tháng#
-- 1. Tạo bảng cha phân vùng theo trường created_at
CREATE TABLE app_logs (
id BIGSERIAL,
level VARCHAR(10) NOT NULL,
message TEXT,
created_at TIMESTAMPTZ NOT NULL,
PRIMARY KEY (id, created_at) -- Partition key bắt buộc phải nằm trong khóa chính
) PARTITION BY RANGE (created_at);
-- 2. Tạo các bảng con tương ứng cho từng tháng
CREATE TABLE app_logs_2026_01 PARTITION OF app_logs
FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
CREATE TABLE app_logs_2026_02 PARTITION OF app_logs
FOR VALUES FROM ('2026-02-01') TO ('2026-03-01');
CREATE TABLE app_logs_2026_03 PARTITION OF app_logs
FOR VALUES FROM ('2026-03-01') TO ('2026-04-01');
Sức mạnh của cơ chế Partition Pruning#
Khi bạn chạy câu truy vấn có điều kiện thời gian:
SELECT * FROM app_logs WHERE created_at >= '2026-02-15' AND created_at < '2026-02-20';
PostgreSQL sẽ thông minh kích hoạt Partition Pruning: Nó chỉ quét duy nhất bảng con app_logs_2026_02 và hoàn toàn bỏ qua tất cả các tháng còn lại, giúp tốc độ truy vấn tăng vọt gấp hàng chục lần!
Xóa dữ liệu cũ của một tháng chỉ mất đúng 1 mili-giây:
-- Thay vì chạy lệnh DELETE chậm chạp, chỉ cần DROP phân vùng:
DROP TABLE app_logs_2024_01;
Góc thảo luận#
Anh em quản lý việc tự động tạo partition cho các tháng tiếp theo bằng cách nào? Dùng extension pg_partman hay viết cronjob chạy script ngoài?
Xem thêm nội dung liên quan:
Thảo luận
1 phản hồi
Tham gia thảo luận
Bài liên quan trong #Backend & Microservices
-
Áp dụng Model Context Protocol (MCP) của Anthropic để kết nối AI với Postgres và Docker
Hoàng Nam (Tech Lead) · 💬 1 -
So sánh mô hình Embedding đa ngữ: OpenAI text-embedding-3 vs BGE-M3 vs Cohere
Minh Trí (AI Engineer) · 💬 1 -
Xây dựng Voice AI Agent thời gian thực với WebRTC và Whisper Live: Độ trễ dưới 500ms
Lan Anh (Senior Frontend) · 💬 1 -
Cấu hình Rate Limiting ở tầng Nginx và API Gateway: Chống DDOS Layer 7 hiệu quả
Đức Huy (DevOps Specialist) · 💬 1 -
Tokenization tiếng Việt của các LLM: Tại sao chi phí tiếng Việt đắt gấp 3 lần tiếng Anh?
Minh Trí (AI Engineer) · 💬 1