PostgreSQL Partitioning: Detayli Teknik Rehber
Tek tablo buyudukce en cok can yakan sorunlar hep ayni olur: yavaslayan sorgular, uzayan vacuum sureleri, index sismesi ve operasyon maliyeti. PostgreSQL partitioning bu sorunlara "tek tus cozum" degil, ama dogru tasarlandiginda ciddi bir olceklenebilirlik avantaji saglar.
Bu yazida PostgreSQL partitioning konusunu teknik ve uygulamali olarak ele aliyoruz.
Partitioning Nedir?
Partitioning, tek bir mantiksal tabloyu birden fazla fiziksel alt tabloya (partition) bolme teknigidir. Uygulama tarafinda tablo yine tekmis gibi gorunur, ama PostgreSQL sorgu planlama asamasinda yalnizca ilgili partitionlari hedefleyebilir.
Ne Zaman Gerekir?
Asagidaki sinyaller varsa partitioning degerlendirilmelidir:
- Tablo satir sayisi hizla buyuyor (ornegin event/log/order tablolari)
- Sorgularin buyuk kismi tarih araligi bazli calisiyor
- Eski veriyi arsivlemek veya toplu silmek sik ihtiyac
- Write throughput artiyor ve maintenance pencereleri daraliyor
Cizim: Mantiksal Tablo ve Fiziksel Partitionlar
+----------------------+
| orders | (parent table)
+----------+-----------+
|
+----------------------+----------------------+
| | |
+-------v-------+ +-------v-------+ +-------v-------+
| orders_2026_01| | orders_2026_02| | orders_2026_03|
| RANGE: Jan | | RANGE: Feb | | RANGE: Mar |
+-------+-------+ +-------+-------+ +-------+-------+
| | |
local index(es) local index(es) local index(es)
Bu modelde parent tabloya query atarsiniz, PostgreSQL ilgili ayi kapsayan partitionlari secer (partition pruning).
Partition Stratejileri
1) RANGE Partitioning
En yaygin modeldir. Genellikle tarih/saat kolonlarinda kullanilir.
CREATE TABLE orders (
id bigserial,
customer_id bigint NOT NULL,
order_date date NOT NULL,
amount numeric(12,2) NOT NULL
) PARTITION BY RANGE (order_date);
CREATE TABLE orders_2026_01 PARTITION OF orders
FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');
CREATE TABLE orders_2026_02 PARTITION OF orders
FOR VALUES FROM ('2026-02-01') TO ('2026-03-01');
2) LIST Partitioning
Degeri ayrik ve sinirli domainlerde iyidir (ulke, tenant tier, status gibi).
CREATE TABLE tickets (
id bigserial,
region text NOT NULL,
created_at timestamptz NOT NULL
) PARTITION BY LIST (region);
CREATE TABLE tickets_eu PARTITION OF tickets FOR VALUES IN ('eu');
CREATE TABLE tickets_us PARTITION OF tickets FOR VALUES IN ('us');
3) HASH Partitioning
Esit dagilim hedefleniyorsa kullanilir. Tarih bazli retention kadar kolay degildir ama write dagilimi icin faydalidir.
CREATE TABLE events (
id bigserial,
user_id bigint NOT NULL,
payload jsonb NOT NULL,
created_at timestamptz NOT NULL
) PARTITION BY HASH (user_id);
CREATE TABLE events_p0 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE events_p1 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE events_p2 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE events_p3 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 3);
Partition Pruning Neden Kritik?
Asil performans kazanci burada gelir. Planner, WHERE kosuluna gore gereksiz partitionlari elemek zorundadir.
Dogru:
SELECT count(*)
FROM orders
WHERE order_date >= DATE '2026-02-01'
AND order_date < DATE '2026-03-01';
Riskli:
-- Fonksiyon kullanimi pruning'i zorlastirabilir
SELECT count(*)
FROM orders
WHERE date_trunc('month', order_date) = DATE '2026-02-01';
Prensip: Partition key kolonunu fonksiyona sokmadan, sargable aralik kosullariyla sorgulayin.
Index Tasarimi: Global Degil, Partition Bazli Dusunun
PostgreSQL'de indexler partition bazinda tutulur. Bu iyi bir sey, cunku:
- Her partition daha kucuk indexe sahip olur
- Reindex/VACUUM etkisi lokallesir
- "Sicak partition" icin farkli index stratejileri uygulanabilir
Ornek:
CREATE INDEX ON orders_2026_02 (customer_id, order_date);
CREATE INDEX ON orders_2026_02 (order_date);
Not: Parent tablo uzerinden index tanimi da yapabilirsiniz; PostgreSQL bunu uygun sekilde partition indexlerine yansitir. Yine de buyuk sistemlerde aktif donem partitionlarini ayrica optimize etmek sik gorulur.
Constraint ve Unique Anahtar Gercegi
Partitioned tabloda unique constraint tasarlarken su kurala dikkat:
- Unique constraint partition key'i de icermelidir (aksi halde tum partitionlar genelinde garanti zorlasir).
Pratikte cogu sistem su yaklasimi kullanir:
- Surrogate primary key (id)
- Is kurali unique'lerini partition key ile birlikte tasarlamak
Operasyonel Bakim (Asil Oyun Burada)
Partitioning bir schema karari oldugu kadar operasyon karari da gerektirir.
1) Gelecek Partitionlari Otomatik Ac
Haftalik/aylik cron ile ileri donem partitionlari onceden olusturun.
2) Retention Politikasi Uygula
Eski veriyi silmek yerine partition drop etmek cok daha hizlidir:
DROP TABLE orders_2024_01;
Bu, milyonlarca satirlik DELETE operasyonundan kat kat ucuzdur.
3) Sadece Sicak Partitionlara Agir Bakim
Aktif yazilan partitionlarda autovacuum ayarlari daha agresif olabilir; soguk partitionlarda daha sakin.
Canli Sisteme Migration Stratejisi
Var olan buyuk bir tabloyu bir gecede partitionlamak risklidir. Daha guvenli yol:
- Yeni partitioned parent tabloyu olustur
- Yeni yazmalari bu tabloya yonlendir
- Eski veriyi batch ile backfill et
- Dogrulama queryleri calistir (count/checksum)
- Uygun zamanda atomik gecis (rename/switch)
Milyarlarca kayitta "zero/minimal downtime" icin dual-write veya CDC temelli gecis de degerlendirilebilir.
Gozlemlenebilirlik ve Dogrulama
Partitioning sonrasi "gercekten kazandik mi?" sorusunu metric ile cevaplayin:
EXPLAIN (ANALYZE, BUFFERS)ile planlari karsilastir- Okunan page sayisi azaldi mi?
- P95/P99 query latency duzeldi mi?
- Vacuum ve bloat davranisi nasil degisti?
Partition pruning calismiyorsa en iyi mimari bile beklenen faydayi uretmez.
Sık Yapılan Hatalar
- Partition key'i sorgu desenleriyle uyumsuz secmek
- Fazla partition acarak planner maliyetini arttirmak
- Partition olusturma/retention otomasyonunu kurmamak
- "Partition varsa her sey hizlanir" varsayimi yapmak
Sonuc
PostgreSQL partitioning, ozellikle zaman bazli buyuyen tablolarda performans ve operasyon acisindan ciddi avantaj saglar. Ancak basari; dogru partition key secimi, pruning dostu sorgu yazimi ve disiplinli operasyon otomasyonuyla gelir.
Kural basit: Partitioning'i sadece schema degisikligi olarak degil, uzun vadeli veri yasam dongusu tasarimi olarak ele alin.