Database Partitioning

แบ่งตารางใหญ่เป็น “ตารางย่อย” หลายตัวที่มี schema เหมือนกัน — ยังอยู่ใน database instance เดียว (ต่างจาก Database Sharding ที่แบ่งคนละ server)

เปรียบเทียบ: Partitioning = แบ่งห้องในบ้านหลังเดียว / Sharding = แยกบ้านหลายหลัง

Horizontal vs Vertical Partitioning

  • Horizontal (ที่คนพูดถึงเป็นหลัก) — แบ่งตาม rows (แต่ละ partition มี row คนละชุด)
  • Vertical — แบ่งตาม columns (เช่น แยก BLOB ใหญ่ไว้ tablespace ของตัวเองที่ disk ช้ากว่าได้)

Partitioning Types (Horizontal)

-- 1. By RANGE
CREATE TABLE sales_2023 PARTITION OF sales 
  FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');
 
-- 2. By LIST
CREATE TABLE customers_west PARTITION OF customers 
  FOR VALUES IN ('CA', 'OR', 'WA');
 
-- 3. By HASH
CREATE TABLE orders_p0 PARTITION OF orders 
  FOR VALUES WITH (modulus 4, remainder 0);

Pros

  • Query ที่เข้า partition เดียว → เร็วขึ้นมาก (partition pruning)
  • Sequential scan ใน partition เล็ก เร็วกว่า scattered index scan ใน table ใหญ่
  • Bulk loading ง่าย — สร้าง partition ใหม่ → attach
  • Archive ข้อมูลเก่าง่าย — ย้าย partition ไป slow/cheap storage

Cons

  • UPDATE ที่ทำให้แถวต้องย้าย partition (เช่น เปลี่ยนวันที่) → ช้าหรือ fail
  • Query ที่ไม่มี partition key ใน WHERE → scan ทุก partition → ช้ากว่า table ปกติ!
  • Schema changes (ALTER TABLE) ทำยากขึ้น

Demo: Partitioning ใน Postgres

-- สร้าง parent table
CREATE TABLE grades_parts (id SERIAL, g INT) PARTITION BY RANGE(g);
 
-- สร้าง partitions
CREATE TABLE g0035 (LIKE grades_parts INCLUDING INDEXES);
ALTER TABLE grades_parts ATTACH PARTITION g0035 FOR VALUES FROM (0) TO (35);
 
CREATE TABLE g3560 (LIKE grades_parts INCLUDING INDEXES);
ALTER TABLE grades_parts ATTACH PARTITION g3560 FOR VALUES FROM (35) TO (60);
 
-- เปิด partition pruning
SET enable_partition_pruning = on;
 
-- Test
EXPLAIN ANALYZE SELECT count(*) FROM grades_parts WHERE g = 30;
-- → เข้าแค่ partition g0035 เท่านั้น

Pitfall ที่เจอบ่อยที่สุด

Partition ตามผิด column — เช่น partition by created_at แต่ query ส่วนใหญ่ใช้ user_id → DB ต้อง scan ทุก partition → แย่กว่าเดิม

ก่อน partition ต้องวิเคราะห์ query patterns ก่อนเสมอ

Key Points

  • Partitioning = แบ่งใน DB เดียว — ต่างจาก Database Sharding
  • 3 ประเภท: Range, List, Hash
  • Partition pruning = query เข้าแค่ partition ที่ต้องการ → เร็วขึ้นมาก
  • Query ไม่มี partition key → scan ทุก partition → ช้ากว่าเดิม
  • ต้องวิเคราะห์ query patterns ก่อน partition เสมอ
  • Database Sharding — แบ่งคนละ server (ระดับถัดไปจาก partitioning)
  • PostgreSQL — demo partitioning, EXPLAIN ANALYZE
  • Database Indexing — index ภายใน partition ยังทำงานปกติ