Veriye Etkin Erişim Yöntemleri – 2

Herkese Selam,

Bu yazıda sizlerle daha önce yazmaya başlamış olduğum Veriye Etkin Erişim Yöntemlerini kaldığım yerden anlatmaya devam edeceğim. Veriye Etkin Erişim Yöntemleri – 1 başlıklı yazımda bu konuya bir giriş yapmıştım ve selectivty üzerinden hangi erişim yöntemlerinin uygulanabileceğini anlatmıştım. Bu yazıdada selectivity si zayıf (Weak) sorgularda uygulanan veri erişim yöntemini anlatacağım.

selectivty

Selectivity’nin zayıf olduğu durumlarda optimizer’ın aşağıdaki veri erişim yöntemlerinden birini kullanması muhtemeldir. Şimdi bu yöntemleri sırası ile inceleyelim.

-Full Table Scans

– Full Partition Scans

– Full Index Scans

FULL TABLE SCANS

Basit bir ifade ile tabloya ait tüm data bloklarının okunduğu veri erişim yöntemidir. Okunacak tüm data blokları o tabloya ait High Water Mark’ın gösterdiği noktanın altında kalan data bloklarıdır. High Water Mark daha önceki yazılarımda da anlattığım üzere tablo insert aldıkça seviyesi yükselen bir pointer’dır. Ne zaman ilgili tablo ile alakalı bir FULL TABLE SCAN kararı optimizer tarafından alınırsa ozaman ilgil HWM’ın gösterdiği noktanın altındaki tüm data blokları okunur.

1

Buraya kadar her hangi bir problem yok ancak tablo delete aldığı durumlarda HWM’nin konumu değişmemekte. Buda FULL TABLE SCAN kararı çıkmış sorgularda çoğu zaman fazladan okuma yapılarak performansın düşmesi anlamına gelmekte. Bu tarz durumlarda FULL TABLE SCAN performansını arttırmak için HWM’ın yerini değiştirecek operasyonlar yapmak gerekmektedir. Bu operasyonlar;

– Alter Table Enable Row Movement

–  Alter Table Shrink Space

gibi operasyonlardır. Eğertablo içinde tüm datayı temizliyeceksek ve bu datanın rollback edilmiyeceği konusunda eminsek bu durumdada truncate table deyimini kullanarak HWM nin yerini değiştirip FULL TABLE SCAN performanslarımızı arttırabiliriz. High Water Mark ile ilgili detaylı bilgiye Oracle’da High Water Mark Kavramı başlıklı yazımı okuyabilirsiniz.

Şimdi bir örnekle bu durumu inceleyelim.

1- 2 Kolonu olan bir tablo yaratalım.

CREATE TABLE hwm_deneme(col NUMBER,col2 VARCHAR2(50));

2- Daha Sonra HWM şuan başlangıç konumundayken tablomuza bir count sorgusu atalım ve ne kadar sürdüğüne bakalım.

SET timing on;
SELECT COUNT (*)
FROM hwm_deneme;
–Elapsed: 00:00:00.25

3- HWM’nin konumunu değiştirmek için tabloya 10 Milyom kayıt yazalım ve bu 10 milyon kayıdı silip yeniden bir count sorgusu atıp ne kadar sürdüğüne bakalım.

BEGIN
FOR i IN 1 .. 10000000
LOOP
EXECUTE IMMEDIATE ‘INSERT INTO hwm_deneme
VALUES (:i, ”HWM_DENEME”)’
USING i;
END LOOP;

COMMIT;
END;

–Tablodaki tüm kayitları temizleyim.

SET timing on;
DELETE      hwm_deneme;

SET timing on;
SELECT COUNT (*)
FROM hwm_deneme;
–Elapsed: 00:00:02.06

Evet örnekten de görüldüğü gibi tablomuzda kayıt olmamasına rağmen HWM’nin gösterdiği yer insert işlemi sonunda gösterdiği nokta olduğu için Oracle boş yere I/O yapmak zorunda kalmıştır. Bundan dolayı sorgumuzun çalışma süresi, tabloyu ilk yarattığımızda çalıştırdığımız sorgumuzun süresine göre daha yavaş olmuştur.

Partitioning

Selectivitynin çok zayıf olduğu durumlarda full table scan yapmak veriye erişmek için en etkili yöntem ancak selectivitynin  sıfıra yaklaşmaya başladığı durumlarda bir çok blok gereksiz yere okunmaya başlanır. Selectivitynin zayıf ancak sıfıra yaklaşmaya başladığı durumlarda index kullanmakta efficient bir yöntem değildir. Bu tarz durumlarda logical reads sayısını düşürmek için seçilecek en etkin yöntem partitionlamadır. Partitioning datayı verdiğimiz koşullar doğrultusunda fiziksel parçalara bölerek ilgili parçaları aynı fiziksel alanda tutma yöntemidir. Oracle’ın en güçlü özelliklerinden’de biridir. Partition’lı bir tabloda Optimizer gelen sorguya bakarak ilgilenmediği partitionları okumadan sadece ilglendiği partitionları okuyarak selectivity’si zayıf olan sorgularda ciddi performans artışları sağlamaktadır. Partitioning temelde 3 farklı şekilde yapılabilir bunlar;

Range Partition: Doğal olarak sıralı olan durumlarda örneğin belirli bir zaman aralığında öncesinde sonrasında..

List Partition: Distinct değer sayısı limitli olan kolonlar için önerilir. Örneğin, cinsiyet, status,country,postal_codes gibi

Hash Partition:Distinct değer sayısı çok fazla olan kolonlar için kullanılması önerilir. Örneğin customer_id, sales_id …

part1

part2

Şimdi bir örnek ile Partitioning yapılan bir sorguyu inceleyelim.

part3Sorgu geldiğinde optimizer where conditionına bakar ve partition keyin join conditionını inceleyerek ilgili datayı hangi partitionda arayacağını data dictionary ye bakarak karar verir ve ilgisi dışında olan partitionları budar (Partition pruning). Partition pruning yapılabilmesi için partition keylerin where koşulunda mutlak suretle olması beklenir aksi takdirde optimizer’ın datanın hangi partitionda aranacağını bilemez ve tüm partitionları tarayarak full table scan yapmak zorunda kalır.

Yukarıdaki örnekte data 12 ay’a(d1) ve her ayda kendi içinde 4 parçaya bölünmüş(n1)  toplam 48 partition’lı bir tablo görmekteyiz. Bu tabloya yukarıdaki sorgu geldiğinde n1=3 olan kayıtların bulunduğu partition ile d1= ‘2007-07-19’ tarihine denk gelen partitionların kesiştiği nokta bulunur. Bu bulunan partition gerçekten aradığımız datanın bulunduğu partition’dır. Yalnızca bu partition’ın okunması bizim için yeterli bir durumdur. Bu işlem kaynaklı performansımız oldukça gelişecek ve fazladan lojik,  fiziksel okuma yapıp kaynaklarımızı meşgul etmeyeceğiz.

FULL INDEX SCANS

ind1

Index ler yalnızca, kendileri üzerinden rowid listesi çıkarıp bu rowidlere karşılık kayıtları bulmak için tablolara gitmezler, indexler doğal olarak tablo üzerindeki bir yada birden çok kolonu key olarak(composite yada composite olmayan indexler) aldıklarından ötürü üzerlerinde key olarak aldığı data yıda barındırmaktadırlar. Eğer gelen sorgunun dönüşü index key’in olduğu kolon ise rowid’yi alıp tabloya gitme gereksinimi kalmadan index keyi okuyup geriye sorgu sonucu olarak döndürebilmektedir. Bu sayede çok önemli bir veri erişim optimizasyonunu oracle kullanıcılarına sağlamaktadır.

Eğer index querry nin ihtiyaç duyduğu tüm datayı üzerinde barındırıyorsa, full table scan, full partition scan yerine full index scan yapılarak sorgu sonucu döndürülür. Full index scan, full table ve full partition scana göre çok daha efektif ve az lojik okuma yapan bir yöntemdir. Bunun nedenide index segmentlerinin tablo segmentlerinden daha ufak olmasıdır.

Örneğin customer tablomuz üzerinde customer_id kolonu üzerinde bir index olsun. customer tablosuna şöyle bir select gönderirsek;

select customer_id from customer where customer_id >500;

Sorgu sonucu disk üzerinde bulunan tabloya ait data bloklarına gitmeden direk döner. Çünkü sorgunun cevabı doğrudan index içinde mevcut, Oracle bu durumda full index scan yaparak tüm datayı indexten okur ve işlemi bitirir.

Eğer index buffer cache de yoksa, index disk üzerinden getirilmeye başlanır. İndexin büyük olduğu durumlarda okunacak blok sayısı artacağından dolayı daha fazla blok okuması yapılacak. Index full scan yöntemi blokları tek tek okuduğundan toplam blok sayısı, toplam okuma sayısına eşit olucak ve yöntem inefficient hale gelicek. Bu tarz durumlarda multiblock read tekniğini kulnnabilen index_fast_full scan yöntemini gerekli hinti verek kullanmak okuma sayısını düşürüp etkin bir yönteme sistemizmizi tekrar çevirebilir.

Yukarıda  anlattığım yöntemlerin her biri nitelikli Oracle’kaynaklarında ayrı ayrı chapter’lar şeklinde anlatılan konulardır daha detaylı bilgi için referans verdiğim kaynakları takip edebilirsiniz. Umarım farkındalık anlamında faydalı bir yazı olmustur.

Kaynaklar:

TroubleShooting Oracle Performance, Christian Antognini, 2008

“Expert Oracle Database Architecture 2011″, Tom KYTE

http://www.dba-oracle.com/art_9i_indexing.htm

tahiti.oracle.com

docs.oracle.com

Advertisements

About ... from Emrah METE

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

One Response to Veriye Etkin Erişim Yöntemleri – 2

  1. Pingback: Veriye Etkin Erişim Yöntemleri – 3 | Emrah METE

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