Bu makalemizde Oracle ile ilgili bellek yapısına kısa bir giriş yaptıktan sonra performansı artırmak için uygulayabileceğimiz bazı teknikleri inceliyor olacağız. Performans konusuna girmeden önce yazımızın ilerleyen bölümlerinde kullanacağımız bazı terimleri kısaca açıklamak istiyorum. Özellikle terimleri ingilizce olarak veriyorum ki daha net anlaşılabilsin.
Mantıksal olarak veri tutan en küçük veri birimi (Data Block) veri bloklarıdır. Küçükten büyüğe doğru
extent ,segment ,tablespace ve database olarak devam eder.
Tablespace fiziksel olarak ise OS blokları ve data file'lardan oluşur.
Tablespace'leri bir dosya sistemindeki klasör gibi nitelendirebiliriz. Oracle verileri datafile bazında 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.
*** Veritabanı yapısını ikiye ayıracak olursak ;
OLAP(Online Analytic Processing). raporlama sistemidir diyebiliriz yani 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(insert,update,delete) 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.
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.
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. :
*** 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ı Artıracak Teknikler
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 H.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 bellek yapısına kısa bir göz attıktan sonra veritabanımızı nasıl daha etkili hale getip performansını iyileştirebileceğimizi gördük. Umarım yararlı olmuştur.