Các gợi ý để partition bảng sao cho hiệu quả
Giới thiệu
Ở bài viết trước, tôi đã giới thiệu đến các bạn khái niệm về partitioned table. Nếu bạn nào chưa đọc, có thể tham khảo tại link sau nhé:
Trong phạm vi của bài viết này, tôi sẽ đưa ra 1 vài gợi ý để trả lời cho câu hỏi: “Làm sao để partition bảng để đạt hiệu quả cao nhất?”. Chúng được đúc rút từ kinh nghiệm thực tế và kiến thức nghiên cứu từ nhiều nguồn của tôi.
Ok, vào nội dung luôn thôi.
Đặt vấn đề
Trước tiên, khi bạn đã nhắm được 1 bảng có đủ yếu tố để trở thành bảng partition, bạn sẽ có 1 vài câu hỏi cần trả lời:
Lựa chọn cột nào làm partition key?
Nên chọn loại partition nào: Range, List hay Hash partition?
Nội dung tiếp theo, tôi sẽ gợi ý bạn cách trả lời câu hỏi này. Tuy nhiên, đây chỉ là những gợi ý tương đối, bạn hãy áp dụng 1 cách linh hoạt nhé.
Lựa chọn cột nào làm partition key?
Bạn có thể tạo nhiều index trên 1 bảng, tuy nhiên, chỉ có 1 partition key duy nhất mà thôi. Hơn thế nữa, sau khi bảng đã được partition theo partition key, việc thay đổi nó sau này là rất khó khăn và phải đi qua nhiều bước.
Do đó, bạn nên lựa chọn cột làm partition key thật kỹ càng, để tránh phiền phức sau này, cũng như đạt hiệu quả mong muốn.
Một số gợi ý của tôi về việc lựa chọn cột nào làm partition:
- Ứng viên để lựa chọn làm partition key chính là các cột thường xuyên xuất hiện trong mệnh đề WHERE. Với gợi ý này, bạn đã loại bỏ được kha khá các cột khác không đủ tiêu chuẩn làm partition key rồi đấy.
- Cột nào có nhiều giá trị 1 tý có thể cân nhắc làm partition key. Cột gioi_tinh với chỉ có 2 giá trị Nam và Nữ, thì có lẽ không cải thiện được hiệu năng nhiều rồi.
- Các giá trị trong cột nên được phân phối đều 1 chút. VD: Cột cap_bac với 3 giá trị: Nhân viên, trưởng phòng và giám đốc. Mà số nhân viên chiếm tới 90% tổng nhân sự thì lựa chọn cột này làm partition key không ổn đâu!
- Các cột có kiểu varchar, mà giá trị có thể là bất cứ thứ gì, không nên lựa chọn là partition key. VD: Cột ho_ten !
Nếu bảng của bạn có chính sách định kỳ cut off/archive) dữ liệu ( tức là định kỳ sẽ xóa hoặc move các dữ liệu đã cũ sang chỗ khác), thì cột điều kiện để archive dữ liệu (VD cột created_date) có thể được lựa chọn làm partition key. Làm như vậy, việc cutoff hay archive dữ liệu của bạn sau này sẽ rất nhàn.
Nên chọn loại partition nào cho bảng?
Có rất nhiều kiểu partition bảng: Range partition, List partition hay Hash partition. (Còn vài kiểu partition nữa nhưng ít dùng)
Vậy nên lựa chọn loại nào?
1. List partition
Đặc điểm:
Bảng sẽ được phân chia thành các partition dựa trên các giá trị của cột partition key, các giá trị này là hữu hạn và rời rạc (discrete value). VD: Cột quoc_gia có các giá trị: VN, US, CN, JP,.., mỗi giá trị sẽ ứng với 1 partition.
Cách dùng:
- Sử dụng khi partition key bao gồm các giá trị không có thứ tự cụ thể
- Các cột partition key thông thường dùng cho List partition, ví dụ như: chi_nhanh, phong_ban, san_pham, …(chỉ bao gồm các giá trị, mà không có thứ tự cụ thể.
VD:
2. Range partition
Đặc điểm:
Range partition sẽ chia bảng ra thành các partition dựa trên việc chia khoảng các giá trị của cột partition key.
Cách dùng:
- Nếu các giá trị của cột partition key có thể là bất cứ giá trị nào, nhưng có thể sắp xếp chúng theo thứ tự cụ thể, range partition sẽ được sử dụng.
- Thường sử dụng cho các partition có data type là date, datetime hoặc number. VD như: cột created_date, ngay_mua, ngay_thanh_toan, …
- Đa số các bảng parttioned table mình gặp là Range partition.
VD:
3. Hash partition
Đặc điểm:
- Các dòng dữ liệu sẽ được phân phối ngẫu nhiên vào các partition, bằng cách sử dụng 1 hàm hash value cột partition key.
- Mỗi khi có dữ liệu mới, hash value sẽ được tính toán và quyết định dữ liệu đó sẽ thuộc về parttion nào.
- Với kiểu Hash partition, các parttion sẽ có dữ liệu đồng đều như nhau.
Cách dùng:
- Thường dùng khi giá trị của partition key là ngẫu nhiên, không có thứ tự. VD như: cột mã khách hàng, mã hóa đơn, mã giao dịch,…
- Áp dụng khi bạn muốn tăng tốc truy vấn bằng xử lý song song (parallel query)
VD:
Trên đây là một vài gợi ý của tôi về cách partition bảng sao cho hiệu quả. Nếu bạn thấy có chỗ nào chưa chính xác, hoặc có thể bổ sung thêm, hãy để lại bình luận cho tôi biết nhé.