11 Aralık 2010 Cumartesi

CBO ve Karmaşıklığı

Selamlar,

Biliyorum, bir aydır herhangi bir giriş yapamadım ama yüksek lisansım hızlı bir şekilde ilerlediğinden dolayı biraz boşladım açıkçası fakat yazmaya devam edeceğim.

Oracle veritabanı, CBO (Cost Based Optimizer) adında çok karmaşık bir yapıya sahip. Bu yapının temel amacını aslında daha önceki girişlerimde belirtmiştim. Kısaca, yeniden belirtmem gerekirse CBO, verilen SQL'i hangi yol ile çalıştıracağını tespit eden bir sistem. Bu sistem aslına bakarsanız oldukça faydalı ve en düşük maliyetli sorgu yolunu seçmekte başarılı. Ancak bunun da bir yere kadar gidiyor olması gerekiyor çünkü en nihayetinde bir otomizasyon ve araç.

CBO kimi zaman tablo üzerindeki istatistikler güncel olsa bile doğru sonucu vermiyor olabilir. Burada dikkat, CBO zaten doğru sonuca gidiyor ama "optimum" sonuca gitmiyor olabilir. Bu da şu demek oluyor, CBO kendi hesapladığı maliyeti en düşük olan çalıştırma yoluna girer. Bunu da tablo üzerindeki istatistikleri baz alarak yapar.

Geçtiğimiz günlerde başıma gelen bir olaydan bahsetmek istiyorum. Üzerinde sorgu hazırladığım ve çalıştığım tablonun toplam boyutu yaklaşık 600GB kadar ve satır sayısı da 1 milyar 200 milyon civarında. Neyse ki performans açısından oldukça iyi durumdayız (!) çünkü bu tablo günlük partition'lara ayrılmış bir tablo. Tablo üzerinde 8 tane sütundan oluşan bir composite PK (Primary Key) indeksi bulunmakta ve tablodaki istatistikleri yeni toplamıştım. Fakat üzerinde çalıştığım sorgu bana çok düşük bir cost ve indeks kullanımı gösterse de sadece 96 satırı istediğim bir sorgunun bana gelmesi 16 dakika sürüyordu. Buradaki önemli nokta veritabanında herhangi bir wait event bulunmamaktayken bana bunu yapıyordu.

Her zamanki gibi en iyi dostum olan ADDM'e başvurdum. Sordum, bana PK indeksi kullandığını, join yaptığım tablo için de indeks kullandığını gösteriyorsun ey CBO. Peki neden nested loop ile de birleştirmene rağmen bana istediğim sonucu, istediğim zamanda vermiyorsun? Bana verdiği tek bir cevap vardı. "Indeks". Verdiği indeks cevabı aslında ilk bakışta garip geliyor çünkü zaten PK'nın kavradığı bir partitioned indeks'e sahibim ama ADDM'in bana önerdiği indeks 8 değil, 4 composite indeks sütunundan oluşuyordu.

Üzerinde çalıştığım sorgu bloğu oldukça karmaşıktı ve where ifadesinde yaklaşık 5 ayrı eşitlik bulunuyordu ve bu büyük tablonun dışında bilgi çekmem gereken bir başka referans tablosu daha bulunuyordu.

ADDM'in dediğini yerine getirdim ve partitioned indeksimin yaratılmasına başladım. Indeksi önceki gece 9'da yaratmaya başladım ve ertesi gün 12:30'da tamamladı. Sonuçlar karşısında gerçekten çok şaşırdım. O benim 16 dakika süren sorgum 97 milisaniyede geliyordu.

İndeks konusunda daha önce seminerina katıldığım Richard Foote, bu arkadaşlarla ciddi anlamda ilgileniyor ve çok ilginç noktalara değiniyor. Bu noktalardan yola çıkarsak; işte tam bu örnekte olduğu gibi kimi zaman CBO yanılabiliyor ve unutmayın ki CBO maliyeti en düşük sorgunun en hızlı olması gibi bir düşünce kesinlikle doğru değil. Benim çalışmalarımda /*+ FULL(TABLO_ADI) */ hint'ini kullandığım zaman sorgunun maliyeti 100 katına çıkıyordu (CBO'ya göre) ve CBO bu yüzden tercih etmiyordu fakat bu hint ile sorgu 16 dakika değil, 4 dakikada geliyordu. CPU sayısına göre PARALLEL(TABLO_ADI, DEFAULT) hint'i ile de biraz daha hızlandırılabiliyordu.

Sonuç olarak bu yazımda ifade etmek istediğim nokta, her zaman sorgulayın. Diagnostic Pack satın aldıysanız mutlaka SQL Tuning Set oluşturun ve sorgunun ne durumda olduğunu kontrol edin. SQL Tuning Advisor'ın söylediklerini dinleyin CBO'nun değil. CBO %100 doğruya gidecek diye birşey asla yok. Herşeyi Oracle'a bırakmayın, sistemin mutlaka rutin kontrollerini yapın, ağır sorguları yeniden, yeniden inceleyin. Unutmayın, indeks kullanmak her zaman daha hızlı değildir. Indeks'lerin de tipleri ve çalışma mantıkları vardır. Önce bu mantığın ne olduğunu öğrenin ve "full table scan" ile farkı nedir bunu anlayın.

Önümüzdeki haftalarda daha da yoğun olacağım için detaylı, teknik bir bilgi paylaşamayabilirim ancak benim yorumlarımı Oracle Forum'larından takip edebilirsiniz.

Hiç yorum yok:

Takip et: @oganozdogan