Koray Kırdinli

Yazılım ve İş Yaşamı Hakkında Paylaşımlar

Oracle Sql Tuning’e Bir Çırpıda Bakış

Bu makalemizde Oracle ile ilgili bazı temel bilgilere ve özellikle de performans konusunu inceleyeceğiz. Oracle ile performans konusuna girmeden önce konuyla ilgili Oracle veri blokları ve bellek yapısını az da olsa anlamakta fayda var diye düşünüyorum. Temel kavramları anladıktan sonra üzerine inşa etmek daha kolay olacaktır.

Veri Blokları
Data Block :
Mantıksal olarak veri tutan en küçük veri birimidir. Küçükten büyüğe doğru
Extent ,Segment ,Tablespace ,Database olarak devam eder.
Fiziksel olarak ise OS blokları ve data file lerdan oluşur.
Tablespace : Bir dosya sistemindeki klasör gibi nitelendirebiliriz. Mantıksal olarak datafile bazında verileri fiziksel olarak gruplar. Schema ise tablespace’den farklı olarak mantıksaldır ve kullanım hakları ile ilgili bir gruplama yapar. Yani bir schema bir kullanıcının kullanmaya yetkili olduğu objeleri tutar. Bir kullanıcı bir tablespace’deki bütün objeleri kullanamayabilir.

*** : Performans faktörlerinden bir tanesini sistemin nasıl bir sistem olduğu etkiler. İki türlü sistem vardır. Bunlar OLAP(Online Analytic Processing).  yani raporlama sistemi büyük select sorguları çalıştırılır , diğeri ise OLTP (Online Transaction Processing) bu sistemde de küçük sorgular ancak çok kullanıcılı ve yoğun bir sorgu trafiği vardır.
Sistem türüne göre block size’lar belirlenmeli ve gerekli optimizasyonlar yapılmalıdır.
Örneğin çok büyük miktarda veri raporlanıyorsa data bloklar büyük set edilmeli çünkü bir seferde (1 fiziksel okumada)getirilecek veri miktarı daha fazla olur.

Bellek Yönetimi
Oracle yapı itibari ile SGA(System Global Area) ve PGA(Program Global Area) olmak üzere 2 tür bellek yapısı vardır.Bu yapıda SGA bütün veritabanı kullanları için ortak iken PGA ise connection bazlı olarak açılır. bu memory alanları Oracle’da performansı direk olarak  etkiler.Belleklerin iyi paylaştırılması ciddi anlamda performans kazandırır.Zaten tunning yaparken en çok karşımıza sorun olarak IO çıkacak yani performamızı belirleyen en önemli kriterlerden bir tanesi fiziksel okuma. Ne kadar az diske gidersek o kadar hızlanacağımızı aklımızın bir köşesinde tutalım.

*** : Ne kadar az fiziksel diske gidersek o kadar yüksek performans sağlarız. Bellekten çalışmak diskten çalışmaya göre daha hızlıdır.

Yukardaki şekilde de görülen yapıları bizim için önemli olanları kısaca tanımlayalım.
Library Cache : Her sql sorgusu çalıştırıldığında sorgu parse edilir ve bir tane execution plan denilen bir plan oluşturur. Bu plan hangi tabloda hangi indexler ile nereye bağlantı yapıldı , costu ne gibi bir takım özellikleri barındırır. İşte bir sorgu bir kez çalıştırıldığında oluşan execution plan bu bellek alanına yazılır. Eğer aynı sorgu bir kez daha çalıştırılırsa eğer Library Cache’te varsa tekrardan sorguyu parse etmez ve aynı planı kullanarak performans kazanır.
Data Dictionary Cache : Sql cümlesi bir tabloya erişmeye çalıştığında (SELECT * FROM tablo1) bu tabloya select atma hakkı var mı , bu tablonun istatistikleri neler gibi bir takım bilgilerin tutulduğu bellek alanıdır.
Buffer Cache : Bir tabloya bellek alanı boşken ilk sefer select sorgusu çalıştırılırsa direk olarak fiziksel diskten okur.Ancak bir kez çalıştıktan sonra bu bellek alanından okuyarak sonucu daha hızlı getirir.
Large Pool : Paralel ve Shared Server gibi işlerde kullanılabilir. Opsiyoneldir.
Log Buffer : Burada transaction bilgileri var. Veritabanı herhangi bir sebepten dolayı kapanırsa buradan son yapılan çalışmaları elde edebiliriz.

Redo Buffer,Java Pool ve Stream Pool

PGA ise kullanıcı bazlıdır. Oracle’a açılan her bir User process için server tarafında bir server process tahsis edilir. Yani her bir kullanıcı için serverda bellekten yer ayrılır.
*** : Gereksiz connectionların hafızadan temizlenmesi performansı artırır.

*** : Oracle 8i de bellek yönetimi tamamen admine bırakılmıştı.Her bir cache e teker teker boyutlarını vermek gerekiyordu.Library Cache’e ayrı Data Dictionary Cache’e ayrı. 10g ile birlikte sadece PGA ve SGA ya bellek alanları vermek durumundaydık , alt cache’lere teker teker verme zahmetinden kurtulmuş olduk. 11g ile birlikte bu yönetimi Oracle tamamen kendisi yapabilmektedir.

Performansınızı Uçurun

1- Tablo istatistiklerinin yanlış olması : Oracle execution plan oluştururken istatistiklere bakar. İstatistiklerde bir tabloda kaç kayıt var vs gibi bilgiler mevcuttur. Eğer sık insert alan bir tablo ise istatistikler sorgu çalışacağı anda yanlış olabilir.

Bunu bir örnekle modelleyelim. Stok adında bir tablomuz olsun başlangıçta 10 kaydımız var diyelim daha sonra toplu birşekilde tabloya import yaptık ve 9000000 kaydımız oldu diyelm. Oracle normal şartlarda sadece belli zamanlarda tabloların istatistiklerini tekrardan düzenler bu yüzden import işlemini yaptıktan sonra istatistiklerde kayıt sayısı hala 10 görülecektir.

SELECT * FROM Stok WHERE Kategori=’Bilgisayar’ sorgusunu çalıştırdık diyelim.

Stok tablomuzda Katagori kolonunda indeksimiz olmasına rağmen kayıt sayısı az olduğunu sanan Oracle bu indeksi kullanmayıp  Full Table arama yapabilir. Bu da sistemi bir hayli yorar. Halbuki istatistikler tam olsa index range scan yaparak çok daha az maliyet ile kayıtları getirebilir.

2- Sorgularda eşitliğin sol tarafında fonksiyon kullanmak index kullanımına engel olur. Örnek
     SELECT * FROM Stok WHERE UPPER(StokAdi)=’KLAVYE’
Bu sorguda StokAdi kolonunda indeks olsa dahi indeks kullanılmaz ve FULL TABLE çalışır.

3-Sub queryleri FROM’a yazmak en hızlısıdır.
Kötü Örnek:
Select Count(*) FROM Stok S WHERE S.Fiyat < 2*(SELECT AVG(Fiyat) FROM StokHareket          SH WHERE S.StokKod=SH.StokKod)

Düzeltilmiş Örnek:
Select Count(*) FROM Stok S ,(SELECT StokKod,AVG(Fiyat) Fiyat FROM STokHareket GROUP BY StokKod ) SH WHERE SH.StokKod=S.StokKod AND S.Fiyat<2.SH.Fiyat

4- Eğer kesişen kayıt almadığından eminseniz UNION kullanmak yerine UNION ALL kullanmak daha hızlı olacaktır. Çünkü UNION ALL kesişen kayıtlarla uğraşarak vakit kaybetmez.

5- WHERE TO_CHAR(Fiyat) = :fiy yerine WHERE Fiyat = TO_NUMBER(:fiy)

6- ORDER BY,NOT IN,IN,UNION,DISTINCT gibi ifadeler kullanılırken dikkatli olmak lazım çünkü maliyeti çok yüksek.

7- Doğru yerde doğru indeks kullanımı çok önemlidir. Nerede indeks kullanmalı konusu  biraz tecrübe ve biraz da sistemin genel yapısı ile alakalıdır.

8- Çok sık değişen ve küçük tablolarda indeks kullanmak çok da doğru değildir.

9- Genel olarak bütün mantığımız execution planı mümkün olduğu kadar az çalıştırtmak. Library Cache mizde yeteri kadar sorgu çalışmış olmalı. Eğer oracle veritabanı uzun süre çalıştıktan sonra kapanırsa açılınca performansı düşük olacaktır çünkü cache’deki bütün execution planlar silinmş olacaktır. O yüzden veritabanını kapatmamalıyız.

10-Materalized View kullanmak : Eğer sık değişen büyük veriniz varsa mutlaka kullanın.

11- Bir sorguda AND ile bağlanan iki filtre varsa WHERE ad=’KORAY’ AND Soyad=’adsds’ ikili index yapmak bu sorguyu daha çok performanslı çalıştırır.

12- Index kullanırken de ne tip index tipini doğru seçmek gerekir. İki tip indeksimiz var. B-tree ve Bitmap Index. Hangisini kullanacağımıza doğru karar vermek çok önemli. Veri tekrarı az ise B-Tree : Örnek kolon stok kodu , Tekrar eden kayıt çok ise Bitmap : Örnek Cinsiyet. Primary Key ve Unique Key kolonlar B-TREE indekse örnektir.

13- Partition Yapalım. Range,Hash,List …vs Partitions.

14- Birden fazla CPU varsa paralel indexlerden faydalanalım.

15- Cluster kullanımı: Örneğin bir adı,soyadı,tel gibi bilgi çok fazla yerde kullanılıyorsa buları cluster haline getirebiliriz. CREATE CLUSTER ….

16- INDEX ORGANIZE TABLE : Bir tablo çok fazla değişmiyorsa tabloyu yaratırken indeksli yaratırız ve sıralı bir şekilde kaydeder.Çok hızlı select yavaş insert. Primary Key şart
CREATE TABLE …… ORGANIZATOIN INDEX

17-  Data dağılımları düzgün tablolar için bind variable kullanmak hız kazandırır.Çünkü ilk seferde sorgunun execution planı oluşturulur ve bir sonraki değeri farklı dahi olsa bir önceki plandan işlem görür. Örnek bölge kolonu için her bölgede aşağı yukarı 99 ile 101 kayıt varsa kullanmak mantıklı.

HINTS : Execution Planlara Hint ile baskıda bulunup değiştirtebiliriz ancak 11g ile artık buna çok fazla da ihtiyacımız kalmadı. Zaten en iyi maliyetli planı Oracle buluyor. Ancak spesific durumlarda ve test amaçlı kullanılabilir.

SELECT /*+ INDEX(t name_idx)*/ FROM tablo t where name=’koray’
Oracle Enterprise Manager
Oracle’ın yönetimsel aktivitelerini takip etmek için kullanışlı bir uygulamadır. Bu bir Oracle servisidir ve uzun süre alan sql’leri akalamktan tutunda sqller ile ilgili tavsiye vermeye kadar bir çok işlevi vardır. Ayrıca incelenmesi gereken bir konudur.Biz sadece bazı küçük modüllerini inceleyeceğiz.
1- SQL Tunning Advisor : Oracle Enterprise menüsü üzerinden bu araca gelerek mevcut bir sorgunuza olumlu bir tavsiye alabilirsiniz. Örneğin şu tabloda şu kolonda index yap gibi. Mutlaka kullanılması tavsiye edilir.

2- SQL Access Advisor : Index ve Partition tavsiyesinde bulunur. Daha detaylı tavsiyeler içerir.

Sonuç olarak yazımızda Oracle yapısına kısa bir göz attıktan sonra veritabanımızı nasıl dah etkili hale getip performansını iyileştirebileceğimizi gördük. Umarım yararlı olmuştur.

Herkese İyi çalışmalar.

November 21, 2009 - Posted by | Oracle | , , , ,

No comments yet.

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