PostgreSQL 11.2 ‘de Table Partitioning Kavramı

Bu yazımızda sizlerle PostgreSQL de Table Partitioning nedir ve avantajları nelerdir sorularının cevaplarını arayacağız.
Biz PostgreSQL 11.2 sürümünde ki Partitioning yapısını ele alıyor olacağız. PostgreSQL 10 öncesinde kullanılan partitioning yöntemi çok manuel bir yapıdaydı ve sıkıntılıydı.
Düşünün ki 10 versiyonundan önce ilgili partitiona veri aktarmak için Trigger kullanılıyordu. Ne kadar eski bir yapı olduğunu siz düşünün.

Tabloyu belirli kriterlere göre parçalamaya partitioning denir. Parçaladığımız ana tabloya master parçalarına ise child denmektedir.

Peki Ne gibi Avantajları olmakta ;

  • Sorgu performansı artmakta. (Sorgulaırmız ilgili partitionda ki datayı çektiğinden tablonun tamamına değilde sadece ilgili partitionda ki datalara dokunarak daha hızlı result dönmekte.)
  • Inde maliyeti ve Size ‘ı azalmakta.Sadece ilgili partition ‘a index atarak hem index lerimizin boyutunu küçültüp hem de inde fragmantasyon larımızın azalmasına olanak sağlamakta.
  • Bulk operasyonlarımızı daha sağlıklı ve hızlı yönetebileceğiz.

Peki Nedir bu Partition Tiplerimiz ?

A. LIST :
PARTITION KEY değeri neyse sadece o değerlere ait veriler parçalanır.
Örneğin status alanı ACTIVE, PASIVE olan değerleri içeren tüm satırlar için ayrıca partition oluşturulması için LIST kullanılır.

B. RANGE :
Belirlenen kriterlere göre tablo bölümlenmesi gerçekleşir. Tarih aralığına bölünebileceği gibi belirli objelere göre partition yapılabilir.
Örneğin belirli tarih aralığı için RANGE kullanılabilir.

C. HASH :
Partition Key’in ait hash değerine göre satır bazlı verilerin partition tablolarına aktarılmasıdır. RANGE ve LIST partitionuna benzer şekilde oluşturulur.
Partition tablolarının oluşturulması sırasında MODULUS ve REMAINDER kavramları var. MODULUS değeri bizim kaç adet partition tablomuzun olduğunu belirtir ve tüm partition tabloları için sabittir ve
değişmez. REMAINDER değeri HASH partition için kullanılan hash key ‘in, yani tablomuzu bölmek için kullanacağımız sütun, hash değerini REMAINDER’e böler ve kalan değer ne ise o
REMAINDER’in bulunduğu partition tablosuna veriyi aktarır.

Örneğin, MODULUS 10 dediğinizde partitioned tablosu 10 adet partition tablosuna sahip demektir ve tüm partition tablolarında sabittir.
REMAINDER 0 dan 9 a kadar tüm değer alır. Böylece tablomuzu hangi sütuna göre böleceksek, o sütunun hash değerini MODULUS değerine böler ve örneğin kalan 3 ise REMAINDER 3
olan partition tablosuna veriyi aktarır.

Şimdi ise demolarımıza geçelim. İlk önce Range Partition örneğinden başlayacağız.

ÖRNEK 1 – Range Partitioning :

İlk etapta demo tablomuzu oluşturalım.

CREATE TABLE satis (
 id serial,
 satis_adedi int,
 satis_tarihi date not null
) PARTITION BY RANGE (satis_tarihi);

Şimdi ise partition larımızı oluşturalım. (Yukarıda demo tablomuzu oluştururken Partition tipimizi ve hangi kolon üzerinden bölünme yapılacağını belirttik. PARTITION BY RANGE (satis_tarihi))

Şimdi Partition larımızı oluşturalım. Burada ay bazlı partition yapacağımızdan tablomuzu son 1 yıl için 12 ye bölümlüyoruz.

CREATE TABLE satislar_2019_01 PARTITION OF satis
FOR VALUES FROM ('2019-01-01') TO ('2019-02-01');

CREATE TABLE satislar_2019_02 PARTITION OF satis
FOR VALUES FROM ('2019-02-01') TO ('2019-03-01');

CREATE TABLE satislar_2019_03 PARTITION OF satis
FOR VALUES FROM ('2019-03-01') TO ('2019-04-01');

CREATE TABLE satislar_2019_04 PARTITION OF satis
FOR VALUES FROM ('2019-04-01') TO ('2019-05-01');

CREATE TABLE satislar_2019_05 PARTITION OF satis
FOR VALUES FROM ('2019-05-01') TO ('2019-06-01');

CREATE TABLE satislar_2019_06 PARTITION OF satis
FOR VALUES FROM ('2019-06-01') TO ('2019-07-01');

CREATE TABLE satislar_2019_07 PARTITION OF satis
FOR VALUES FROM ('2019-07-01') TO ('2019-08-01');

CREATE TABLE satislar_2019_08 PARTITION OF satis
FOR VALUES FROM ('2019-08-01') TO ('2019-09-01');

CREATE TABLE satislar_2019_09 PARTITION OF satis
FOR VALUES FROM ('2019-09-01') TO ('2019-10-01');

CREATE TABLE satislar_2019_10 PARTITION OF satis
FOR VALUES FROM ('2019-10-01') TO ('2019-11-01');

CREATE TABLE satislar_2019_11 PARTITION OF satis
FOR VALUES FROM ('2019-11-01') TO ('2019-12-01');

CREATE TABLE satislar_2019_12 PARTITION OF satis
FOR VALUES FROM ('2019-12-01') TO ('2020-01-01');

Partition işlemimizide tamamladıktan sonra şimdi data girişi yapmadan bir chek edelim.

Aşağıda ki script ile ilgili tablomuzda oluşturduğumuz partition ları çekerek kontrol edebiliriz.

SELECT nmsp_parent.nspname AS parent_schema,
       parent.relname AS parent,
       nmsp_child.nspname AS child_schema,
       child.relname AS child
FROM pg_inherits
JOIN pg_class parent ON pg_inherits.inhparent = parent.oid
JOIN pg_class child ON pg_inherits.inhrelid = child.oid
JOIN pg_namespace nmsp_parent ON nmsp_parent.oid = parent.relnamespace
JOIN pg_namespace nmsp_child ON nmsp_child.oid = child.relnamespace
WHERE parent.relname='satis' ;

Kontrollerimizi de tamamladıktan sonra şimdi tablomuza veri basalım.

INSERT INTO satis (satis_adedi, satis_tarihi) VALUES (50 , '2019-04-12');
INSERT INTO satis (satis_adedi, satis_tarihi) VALUES (80 , '2019-12-14');
INSERT INTO satis (satis_adedi, satis_tarihi) VALUES (70 , '2019-07-15');
INSERT INTO satis (satis_adedi, satis_tarihi) VALUES (75 , '2019-08-17');

Şimdi ise bir sorgu atalım ve gerçekten o ilgili partition dan mı getiriyor sorgumuzu kontrol edelim.

select satis_adedi from satis where satis_tarihi between '2019-04-01' and '2019-05-01';

Şimdi EXPLAIN ederek hangi partition ları kullandığını kontrol edelim.

explain select satis_adedi from satis where satis_tarihi between ‘2019-04-01’ and ‘2019-05-01’;

Gördüğünüz üzere Where bloğunda ki tarih sorgulamalarımızın doğrultusunda satislar_2019_04 ve satislar_2019_05 partitionlaırnı kullandığını görmekteyiz.

Kolay Gelsin.

Leave a Reply

Your email address will not be published. Required fields are marked *