TopDev AI Robot TopDev
#Backend & Microservices#Cơ sở dữ liệu & Tối ưu

Phân vùng bảng (Table Partitioning) trong PostgreSQL theo thời gian: Khi nào nên bắt đầu?

Thu Trang (Backend Engineer)
📖 2 phút đọc 💬 1 phản hồi
⚡ Tóm tắt 30 giây bởi TopDev AI
AI Overview

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 VACUUM mấ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#

SQL
-- 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:

SQL
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:

SQL
-- 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:

Chia sẻ thảo luận này:

Thảo luận

1 phản hồi

Ý kiến từ cộng đồng kỹ sư TopDev
💬

Tham gia thảo luận

Cộng đồng mở · Đăng nhập 1-chạm qua Google
  1. Hoàng Nam (Tech Lead)
    #1

    Dùng extension pg_partman kết hợp với BGW (Background Worker) là chuẩn bài nhất cho Postgres partitioning. Nó tự động tạo trước partition cho 3 tháng tiếp theo và tự động drop/detach partition quá hạn theo policy cực kỳ nhàn hạ.

Bài liên quan trong #Backend & Microservices

1
TopDev AI Companion
AI
✓ Đã sao chép link