Greenplum Database Bài học 16: Thiết kế Partitioning (Phân vùng bảng): Chiến lược Range và List Partitioning cho dữ liệu Time-Series
Trong các bài học trước, chúng ta đã biết cách phân phối dữ liệu ngang hàng qua các Segment bằng DISTRIBUTED BY và tối ưu hóa lưu trữ bên trong từng Segment bằng các mô hình Heap/AOCO kết hợp nén ZSTD. Tuy nhiên, khi một bảng Data Warehouse phát triển đến quy mô hàng chục hoặc hàng trăm tỷ bản ghi (đặc biệt là các hệ thống Logs, IoT, Giao dịch tài chính theo chuỗi thời gian - Time-Series), việc quét toàn bộ bảng dù đã dùng AOCO vẫn sẽ gây tốn kém tài nguyên.
Giải pháp tối thượng tiếp theo để quản lý dữ liệu khổng lồ này chính là Partitioning (Phân vùng bảng). Trong bài học này, chúng ta sẽ mổ xẻ cơ chế phân vùng Range và List Partitioning trên Greenplum và cách nó loại bỏ hàng chục tỷ dòng dữ liệu chỉ trong tích tắc.
1. Bản chất của Partitioning trong Greenplum
1.1. Phân biệt rõ: Distribution (DISTRIBUTED BY) vs Partitioning (PARTITION BY)
Người mới học Greenplum rất hay nhầm lẫn giữa hai khái niệm này. Hãy nhớ quy tắc vàng:
-
Distribution (
DISTRIBUTED BY): Chia nhỏ dữ liệu theo chiều ngang (Horizontal Sharding) ra các máy chủ khác nhau (Segments) qua mạng Interconnect nhằm tận dụng tính toán song song. -
Partitioning (
PARTITION BY): Cắt nhỏ một bảng trên cùng một Segment thành các bảng con nhỏ hơn theo chiều dọc thời gian hoặc giá trị (ví dụ: chia theo từng tháng, từng năm) nằm gọn trong các thư mục ổ cứng riêng biệt.
┌────────────────────────────────────────────────────────────────────────┐
│ DISTRIBUTION vs PARTITIONING │
└───────────────────────────┬────────────────────────┬───────────────────┘
│ │
[ DISTRIBUTED BY (user_id) ] [ PARTITION BY RANGE (created_at) ]
Rải dữ liệu ra các Segment Cắt bảng con theo khoảng thời gian
(Segment 0, Segment 1...) (Tháng 1, Tháng 2, Tháng 3...)
Khi kết hợp cả hai, dữ liệu được phân phối ra các Segment, và trên mỗi Segment lại được chia nhỏ thành các Partition độc lập.
2. Hai chiến lược phân vùng kinh điển: Range và List
Greenplum hỗ trợ 2 hình thức phân vùng dữ liệu chính phù hợp cho từng loại nghiệp vụ:
2.1. Range Partitioning (Phân vùng theo khoảng giá trị / Thời gian)
-
Ứng dụng hoàn hảo: Dữ liệu chuỗi thời gian (Time-Series), lịch sử giao dịch, logs hệ thống, dữ liệu theo ngày/tháng/năm.
-
Cơ chế: Dữ liệu được chia thành các khoảng giá trị liên tục dựa trên kiểu dữ liệu Ngày tháng (
DATE,TIMESTAMP) hoặc Số nguyên (INT,BIGINT).
2.2. List Partitioning (Phân vùng theo danh sách giá trị rời rạc)
-
Ứng dụng hoàn hảo: Dữ liệu phân loại theo khu vực địa lý, trạng thái, mã vùng, loại tiền tệ.
-
Cơ chế: Dữ liệu được gom vào các phân vùng cứng dựa trên tập hợp giá trị cụ thể (Ví dụ: Phân vùng miền Nam, miền Trung, miền Bắc).
3. Cú pháp thực chiến: Thiết kế bảng Time-Series phân vùng theo Tháng
Hãy xem cách thiết kế một bảng giao dịch khổng lồ (fact_transactions) sử dụng mô hình lưu trữ AOCO kết hợp Range Partitioning theo từng tháng và tự động sinh phân vùng:
SQL
CREATE TABLE fact_transactions (
transaction_id BIGINT,
user_id BIGINT,
store_id INT,
amount NUMERIC(12,2),
created_at TIMESTAMP
)
WITH (appendoptimized=true, orientation=column, compresstype=zstd)
DISTRIBUTED BY (user_id)
PARTITION BY RANGE (created_at) (
-- Định nghĩa khoảng thời gian cố định cho các năm trước
START (DATE '2025-01-01') END (DATE '2026-01-01') EVERY (INTERVAL '1 month'),
-- Tự động sinh phân vùng cho năm 2026 (chia đều theo từng tháng)
START (DATE '2026-01-01') END (DATE '2027-01-01') EVERY (INTERVAL '1 month'),
-- Phân vùng dự phòng cho dữ liệu phát sinh ngoài ý muốn (Default / Undefined)
DEFAULT PARTITION extra_fallback_partition
);
4. Phép thuật tối ưu: Dynamic Partition Elimination (Loại trừ phân vùng động)
Lợi ích lớn nhất của Partitioning không chỉ nằm ở việc quản lý file gọn gàng, mà nằm ở một tính năng cực kỳ thông minh của bộ tối ưu hóa GPORCA gọi là Partition Elimination.
Hãy xét câu lệnh truy vấn sau:
SQL
SELECT SUM(amount)
FROM fact_transactions
WHERE created_at >= '2026-06-01' AND created_at < '2026-07-01';
Điều gì xảy ra bên dưới?
-
Nếu không có Partitioning, Greenplum sẽ phải quét toàn bộ các khối dữ liệu của nhiều năm lịch sử.
-
Khi có Partitioning theo tháng, GPORCA nhìn vào điều kiện
WHERE created_atvà nhận ra rằng chỉ duy nhất phân vùng của tháng 6 năm 2026 mới chứa dữ liệu thỏa mãn. -
Phép thuật: Greenplum hoàn toàn bỏ qua (Drop / Skip) 99% các phân vùng của các tháng khác, chỉ mở đúng file dữ liệu của tháng 6 trên các Segment để tính toán. Câu truy vấn từ mất vài phút bỗng chốc hoàn thành trong vài chục mili-giây!
5. Quản lý vòng đời dữ liệu (Data Lifecycle Management & DROP PARTITION)
Trong các hệ thống Data Warehouse, dữ liệu cũ sau vài năm thường ít khi được truy vấn trực tiếp và chiếm dụng dung lượng đĩa lớn. Với bảng thông thường, bạn phải chạy lệnh DELETE FROM ... WHERE ... (thao tác cực kỳ tốn tài nguyên do sinh rác WAL và Table Bloat).
Nhưng với Partitioning, việc xóa dữ liệu cũ trở nên đơn giản và nhanh như chớp nhờ lệnh DROP PARTITION:
SQL
-- Xóa sạch toàn bộ dữ liệu của tháng 1 năm 2025 chỉ trong 0.01 giây
ALTER TABLE fact_transactions
DROP PARTITION FOR (DATE '2025-01-01');
- Bản chất: Greenplum không đi xóa từng dòng dữ liệu, mà nó chỉ đơn giản là gỡ bỏ và xóa sạch file phân vùng tương ứng trên ổ cứng. Thao tác này giải phóng không gian đĩa ngay lập tức mà không gây nghẽn hệ thống.
Tóm tắt Bài học 16
-
Partitioning (
PARTITION BY) giúp cắt nhỏ bảng theo chiều dọc (thời gian hoặc giá trị danh sách), hoàn toàn độc lập với việc phân phối ngang qua các Segment (DISTRIBUTED BY). -
Range Partitioning là chuẩn vàng cho các hệ thống dữ liệu chuỗi thời gian (Time-Series).
-
Partition Elimination giúp bộ tối ưu hóa tự động bỏ qua các phân vùng không liên quan, tăng tốc độ truy vấn lên hàng chục lần.
-
Lệnh
ALTER TABLE DROP PARTITIONcho phép xóa dữ liệu cũ theo chu kỳ một cách tức thì mà không gây tốn tài nguyên hệ thống.
Ở bài học tiếp theo (Bài học 17), chúng ta sẽ tiến sâu hơn vào cấu trúc phân vùng nâng cao: Multi-level Partitioning & Quản lý vòng đời dữ liệu: Tự động hóa cắt/gộp phân vùng.
All Rights Reserved