Merhaba arkadaşlar, bugün sizlere özellikle log tabloları, sensör verileri veya işlem geçmişi gibi sürekli büyüyen devasa tablolarla baş etmenin en etkili yöntemlerinden birini, Partitioning (Bölümleme) stratejilerini anlatacağım. Bu yöntem, performansı artırmanın yanı sıra, eski verileri silme/arşivleme işlemlerini de inanılmaz derecede hızlandırır. Benim sunucularda genelde kullandığım bu yöntemle, birkaç yüz milyon satırlık tablolarda bile sorgu süreleri gözle görülür şekilde düşüyor.
Partitioning Nedir ve Ne Zaman Kullanılır?
Partitioning, tek bir mantıksal tabloyu, fiziksel olarak daha küçük parçalara (partition'lara) bölme işlemidir. Veritabanı motoru, sorgu yaparken sadece ilgili partition'lar üzerinde işlem yapar, böylece tüm tabloyu taramak zorunda kalmaz. Şu durumlarda kesinlikle düşünmelisiniz:
- Tablonuz çok büyük (100GB+ gibi) ve sorgular yavaşlıyorsa.
- Verilerinizin doğal bir bölünebilirliği varsa (örn: tarih, bölge kodu).
- Eski verileri (örn: 2 yıldan eski loglar) hızlıca silmek veya arşivlemek istiyorsanız.
Hangi Partitioning Türünü Seçmeliyim?
En yaygın ve kullanışlı türler şunlar:
RANGE Partitioning: Tarih bazlı bölümleme için biçilmiş kaftan. Örneğin, her ayın verisini ayrı bir partition'da tutabilirsiniz.
LIST Partitioning: Sabit değerlere göre bölümleme yapar. Örneğin, ülke kodlarına veya bölge ID'lerine göre.
HASH Partitioning: Belirli bir sütunun hash değerine göre veriyi dağıtır. Daha dengeli bir dağılım için kullanılır.
Pratik Örnek: Tarih Bazlı RANGE Partitioning
Diyelim ki `server_logs` adında, her gün milyonlarca kayıt atılan bir tablonuz var. İşte bu tabloyu aylık partition'lara bölmek için adımlar:
Öncelikle, partition'lı bir tablo oluşturalım. Şu ayara çok dikkat etmelisiniz: Partition key olarak seçtiğiniz sütun (log_date), tablonun PRIMARY KEY veya UNIQUE KEY'inde mutlaka yer almalı. Yoksa hata alırsınız.
Dikkat Edilmesi Gerekenler
- Planlama: Partition sayısı çok fazla olmamalı. MySQL/MariaDB'de binlerce partition performansı düşürebilir.
- İndeksler: Partitioning, sihirli bir değnek değil. Sorgularınız hala uygun indeksler olmadan yavaş çalışabilir.
- Yedekleme: mysqldump ile tek bir partition'ı yedekleyip geri yükleyebilirsiniz, bu büyük kolaylık sağlar.
- ALTER Table: Var olan büyük bir tabloya partitioning eklemek ÇOK uzun sürebilir. Mümkünse baştan planlayın.
Partition Yönetimi: Eski Verileri Temizleme
İşte en sevdiğim kısım! 2023 Ocak (p202301) ayına ait verileri silmek istiyorsunuz. Normalde `DELETE FROM server_logs WHERE log_date BETWEEN ...` diyerek saatlerce bekleyecekken, partition ile saniyeler içinde hallediyoruz:
Yeni bir partition eklemek de aynı derecede kolay:
Sonuç ve Önerilerim
Partitioning, doğru yerde kullanıldığında hayat kurtarıcıdır. Özellikle zaman serisi verileriniz varsa, ilk bakmanız gereken optimizasyonlardan biridir. Ancak, her sorunun çözümü değildir. Tablonuzun büyüklüğü, erişim şekli ve veri ömrünü iyi analiz edip ona göre karar vermelisiniz.
Ben genelde RANGE partitioning'i, veri saklama politikam (retention policy) ile birlikte otomatize edecek şekilde kullanıyorum. Haftalık bir cron job ile eski partition'ları düşürüp, yeni partition'ları ekliyorum.
Siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Farklı partitioning stratejileri deneyen oldu mu? Takıldığınız veya merak ettiğiniz bir nokta varsa aşağıya yazmaktan çekinmeyin, beraber tartışalım.
Partitioning, tek bir mantıksal tabloyu, fiziksel olarak daha küçük parçalara (partition'lara) bölme işlemidir. Veritabanı motoru, sorgu yaparken sadece ilgili partition'lar üzerinde işlem yapar, böylece tüm tabloyu taramak zorunda kalmaz. Şu durumlarda kesinlikle düşünmelisiniz:
- Tablonuz çok büyük (100GB+ gibi) ve sorgular yavaşlıyorsa.
- Verilerinizin doğal bir bölünebilirliği varsa (örn: tarih, bölge kodu).
- Eski verileri (örn: 2 yıldan eski loglar) hızlıca silmek veya arşivlemek istiyorsanız.
En yaygın ve kullanışlı türler şunlar:
RANGE Partitioning: Tarih bazlı bölümleme için biçilmiş kaftan. Örneğin, her ayın verisini ayrı bir partition'da tutabilirsiniz.
LIST Partitioning: Sabit değerlere göre bölümleme yapar. Örneğin, ülke kodlarına veya bölge ID'lerine göre.
HASH Partitioning: Belirli bir sütunun hash değerine göre veriyi dağıtır. Daha dengeli bir dağılım için kullanılır.
Diyelim ki `server_logs` adında, her gün milyonlarca kayıt atılan bir tablonuz var. İşte bu tabloyu aylık partition'lara bölmek için adımlar:
Öncelikle, partition'lı bir tablo oluşturalım. Şu ayara çok dikkat etmelisiniz: Partition key olarak seçtiğiniz sütun (log_date), tablonun PRIMARY KEY veya UNIQUE KEY'inde mutlaka yer almalı. Yoksa hata alırsınız.
SQL:
CREATE TABLE server_logs (
id BIGINT NOT NULL AUTO_INCREMENT,
log_date DATE NOT NULL,
server_name VARCHAR(50),
message TEXT,
PRIMARY KEY (id, log_date) -- log_date, PRIMARY KEY'in bir parçası OLMALI!
)
PARTITION BY RANGE COLUMNS(log_date) (
PARTITION p202301 VALUES LESS THAN ('2023-02-01'),
PARTITION p202302 VALUES LESS THAN ('2023-03-01'),
PARTITION p202303 VALUES LESS THAN ('2023-04-01'),
PARTITION p_future VALUES LESS THAN (MAXVALUE)
);
- Planlama: Partition sayısı çok fazla olmamalı. MySQL/MariaDB'de binlerce partition performansı düşürebilir.
- İndeksler: Partitioning, sihirli bir değnek değil. Sorgularınız hala uygun indeksler olmadan yavaş çalışabilir.
- Yedekleme: mysqldump ile tek bir partition'ı yedekleyip geri yükleyebilirsiniz, bu büyük kolaylık sağlar.
- ALTER Table: Var olan büyük bir tabloya partitioning eklemek ÇOK uzun sürebilir. Mümkünse baştan planlayın.
İşte en sevdiğim kısım! 2023 Ocak (p202301) ayına ait verileri silmek istiyorsunuz. Normalde `DELETE FROM server_logs WHERE log_date BETWEEN ...` diyerek saatlerce bekleyecekken, partition ile saniyeler içinde hallediyoruz:
SQL:
-- Sadece o partition'ı DROP ediyoruz. Çok hızlı!
ALTER TABLE server_logs DROP PARTITION p202301;
Yeni bir partition eklemek de aynı derecede kolay:
SQL:
-- 2023 Nisan ayı için yeni bir partition ekleyelim.
ALTER TABLE server_logs REORGANIZE PARTITION p_future INTO (
PARTITION p202304 VALUES LESS THAN ('2023-05-01'),
PARTITION p_future VALUES LESS THAN (MAXVALUE)
);
Partitioning, doğru yerde kullanıldığında hayat kurtarıcıdır. Özellikle zaman serisi verileriniz varsa, ilk bakmanız gereken optimizasyonlardan biridir. Ancak, her sorunun çözümü değildir. Tablonuzun büyüklüğü, erişim şekli ve veri ömrünü iyi analiz edip ona göre karar vermelisiniz.
Ben genelde RANGE partitioning'i, veri saklama politikam (retention policy) ile birlikte otomatize edecek şekilde kullanıyorum. Haftalık bir cron job ile eski partition'ları düşürüp, yeni partition'ları ekliyorum.
Siz bu konfigürasyonu kendi sunucularınızda nasıl yapıyorsunuz? Farklı partitioning stratejileri deneyen oldu mu? Takıldığınız veya merak ettiğiniz bir nokta varsa aşağıya yazmaktan çekinmeyin, beraber tartışalım.