Partitioned Tablolarda Local ve Global Indexler

Herkese selam,

Bu yazıda sizlere Oracle veritabanında sık kullandığımız partitioned tablolar üzerindeki indeksleme mekanizmalarından bahsedicem. Umarım farkındalık anlamında faydalı bir yazı olur.

Öncelikle partitioned tablolar hakkında kısa bir bilgi verelim;

Partitioned tablolar kullanıcı tarafından bakıldığında tek bir fiziksel tabloymuş gibi görünsede, veri tabanı seviyesinde partition sayısı kadar fiziksel tablonun var olduğu ve tabloya yeni bir kayıt geldiğinde partition yapımıza göre, gelen kaydın ilgili partition’a yerleştiği bir yapıdır. Partitioning ile tek bir büyük tablo yerine kayıtların belli bir kurala göre dağılmış alt tablolarda olduğunu düşünebiliriz. Bu çok büyük tablolarda sorgu performansımızı arttıracak oracle’ın en etkili özelliklerinden biri olduğunu söylemek yanlış olmayacaktır. İçinde 100 milyon kaydın olduğu bir satış tablosu düşünelim. Bu tabloya sorgu attığımızda sorgunun dönme süresi, bu datanın aylara göre ayrı partitionlarda tutulduğunda sorguladığımız durumdan çok daha yavaş olacaktır(eğer sorgularımızda partition yaptığımız kolona göre bir filtre koyarsak.).

Şimdi partitioned tablo mekanizmasını biraz hatırladıktan sonra,  partitioned tablolarda veriye erişim performansımızı biraz daha arttıracak indeksleme mekanizmasından bahsedelim.

Partitioned tablolarda indeksleme 2 şekilde yapılabilmekte.

1- Global Indeksleme

2- Local Indeksleme

2 indeks tipininde bir birinden farklı özellikleri var şimdi birazcık detaylarına bakalım.

Global Indeksleme

Tablonun partitioned olduğu durumda partition sayısı kadar alt fiziksel tablo oluştuğunu söylemiştik. Eğer tabloda global bir indeks kullanacak isek tüm partitionların üstünde bir index yaratılır ve hangi partitona kayıt gelirse gelsin, kaydın ilgili kolonu indekse eklenir. Bu global indeks tipine Nonpartitioned global index adı verilir.

globalIndex

ancak tablonun çok fazla büyüdüğü durumu düşünürsek indeks te bir hayli büyüyecek ve indeks li erişim performansı da düşecektir. Bu tarz durumda diğer bir çözüm yolu tablo üzerindeki global indeksi de partitionlamaktır. Bu yönteminde terminolojideki karşılığı global partitioned index tir.

Global nonpartitioned index in davranışı, partitioned olmayan bir tablo üzerindeki indeks ile aynıdır. Global partitioned index in davranışı ise bu bağlamda farklılık göstermekte.  Bu farklılığa bakmadan önce nasıl yaratıldıklarına bakalım.

CREATE TABLE satis
(satis_no NUMBER,
satis_tutari number,
satici_id number,
satis_tarihi DATE)
PARTITION BY RANGE(satis_tarihi)
(
PARTITION satis_ocak VALUES LESS THAN(TO_DATE(’01/02/2013′,’DD/MM/YYYY’)),
PARTITION satis_subat VALUES LESS THAN(TO_DATE(’01/03/2013′,’DD/MM/YYYY’)),
PARTITION satis_mart VALUES LESS THAN(TO_DATE(’01/04/2013′,’DD/MM/YYYY’)),
PARTITION satis_nisan VALUES LESS THAN(TO_DATE(’01/05/2013′,’DD/MM/YYYY’)),
PARTITION satis_mayis VALUES LESS THAN(TO_DATE(’01/06/2013′,’DD/MM/YYYY’)),
PARTITION satis_haziran VALUES LESS THAN(TO_DATE(’01/07/2013′,’DD/MM/YYYY’)),
PARTITION satis_temmuz VALUES LESS THAN(TO_DATE(’01/08/2013′,’DD/MM/YYYY’)),
PARTITION satis_agustos VALUES LESS THAN(TO_DATE(’01/09/2013′,’DD/MM/YYYY’)),
PARTITION satis_eylul VALUES LESS THAN(TO_DATE(’01/10/2013′,’DD/MM/YYYY’)),
PARTITION satis_ekim VALUES LESS THAN(TO_DATE(’01/11/2013′,’DD/MM/YYYY’)),
PARTITION satis_kasim VALUES LESS THAN(TO_DATE(’01/12/2013′,’DD/MM/YYYY’)),
PARTITION satis_aralik VALUES LESS THAN(TO_DATE(’01/01/2014′,’DD/MM/YYYY’))
);

Global NonPartitioned Index

globalnonpartitionedIndex

create index npi_satici_id on satis(satici_id);

Global Partitioned Index 

globalpartitioned

 

CREATE INDEX npi_satici_id
ON satis(satici_id)
GLOBAL PARTITION BY RANGE(satici_id)
( PARTITION indp1 VALUES LESS THAN (10),
PARTITION indp2 VALUES LESS THAN (20),
PARTITION indp3 VALUES LESS THAN (30),
PARTITION indp4 VALUES LESS THAN (40),
PARTITION indp5 VALUES LESS THAN (MAXVALUE));

Global partitioned index de dikkat edilmesi gereken husus indeks attığımız kolonun MAXVALUE ile sınırlandırılmış partitionının büyümesidir. Burada yapılması gereken bu kısma düşecek değer içeren kayıtların fazlalaştığı durumda MAXVALUE ile sınırlandırılmış partitionıda split etmek olacaktır. Aksi takdirde indeks in bu partitionindaki entry sayısı büyüyecek ve bu  indeks üzerinden çalışacak sorguların performansı düşecektir.

Burada dikkat etmemiz gereken diğer bir konuda indeks partitionlarından birini sildiğimizde kalan indeksleri kullanabilmemiz icin indeksi yeniden rebuild etmemiz gerekliliğidir.

Şimdi bir indeks partitionını drop edip diğer indeks partitionlarının durumlarına bakalım.

ALTER INDEX npi_satici_id DROP PARTITION indp3;

SELECT partition_name, status
FROM user_ind_partitions
WHERE index_name = ‘NPI_SATICI_ID’

indexdropresult

Örnektende görüldüğü üzere 3 numarali partition ı drop ettiğimiz de bir sonraki indeks partitionının kullanılmaz durumda olduğu gözüküyor. Bu durumu önlemek için aşağıdaki sql cümlesi çalıştırılmalıdır.

ALTER INDEX npi_satici_id REBUILD PARTITION indp4;

SELECT partition_name, status
FROM user_ind_partitions
WHERE index_name = ‘NPI_SATICI_ID’

PARTITION_NAME STATUS
—————————— ——–
INDP1 USABLE
INDP2 USABLE
INDP4 USABLE
INDP5 USABLE

 

Local Partitioned Index

localpartititionedIndex

Local partitioned Index, partition lı tablomuzun her bir partition ı ile ilgili bir index yaratmayı ön görür. Kullanımı ve bakımı diğerlerine göre oldukça kolaydır. Oracle indeks senkronizasyonunu her partition için otomatik yapar ve indeksleri güncel tutar. Her bir index ile bağlı olduğu partition ı çift olarak değerlendirir ve diğer ikililerden bağımsızlaştırır. Bu sayede herhangi bir ikilide yaşanacak problem diğer ikililerde herhangi bir probleme yol açmaz ve indeksler sağlıklı bir şekilde çalışmaya devam eder. Bu durum sadece problemler ile ilgili değil tablo üzerindeki herhangi bir partitionın, başka bir fiziksel diske taşınması gibi durumlarda da sadece ilgili tablo indeks ikilisi bundan etkilenir. Bu sayede tablo sürekli available tutulabilir.

Local Partitioned Index lerde dikkat edilmesi gereken husus, local index e harici bir komutla yeni bir partition ekleyememizdir. Bunu yapmak için indeks atılan tabloya yeni bir partition eklemek indeks e de yeni bir partition eklemek anlamına gelecektir.  Aynı şekilde indeksten bir partition drop edilmesi harici olarak mümkün değildir, bunu yapmak içinde indeksin gosterdiği tablonun ilgili partitionını drop etmek yeterli olacaktır.

CREATE INDEX npi_satici_id
ON satis (satici_id)
LOCAL;

 

Local ve Global Indekslerin özellikleri incelendiğinde, OLTP sistemler için global, OLAP sistemler için local indekslerin kullanılması daha uygun kanısına varılabilir. Ancak bu karar bir genelleme değildir, burada belirleyici olan bizim ihtiyacımızıdır. Temel karakteristikleri anlamında bu yargıyı söylemek mümkün çünkü OLAP sistemler sorgulamanın çok yapıldığı ve OLTP sistemlere göre daha büyük boyutta datanın içeride olduğu sistemler bu yüzden tabloların sürekli available olmaları, partition pruning den sonra dataya erişimin hızlanması konusunda ve raporlamaların kesintisiz yapılabilmesi için çok kritik (DSS).  Bunun yanında Local Index lerin bakımının daha kolay olduğunu daha öncede söyledik. Global Indeksi etkileyecek herhangi bir bakım çalışmasında tüm global indeks in yeniden rebuilt edilmesi gerekebilir.

Umarım farkındalık anlamında faydalı bir yazı olmuştur.

Kaynaklar:

TroubleShooting Oracle Performance, Christian Antognini, 2008

“Expert Oracle Database Architecture 2011″, Tom KYTE

http://docs.oracle.com/cd/B10500_01/server.920/a96524/c12parti.htm

 

Advertisements

About ... from Emrah METE

Bilgisayar Mühendisi
This entry was posted in Oracle, Uncategorized and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s