Neden Oracle Oluşturulan İndex’i Kullanmıyor? (Oracle Function-Based Index Oluşturma)

İlişkisel Veritabanı Yönetim Sistemleri (RDBMS) ‘nde veriler tablolarda tutulmaktadır ve tablolar arasında da Primary Key – Foreign Key kullanılarak ilişkiler tasarlanmaktadır. Kullanıcılar veritabanındaki tablolarda bulunan ilgilendikleri verileri SQL sorguları vasıtasıyla çekmektedirler. Yazılan SQL sorgusuna bağlı olarak, kullanılan veritabanı yönetim sistemi optimizerı, veriye bütün tabloyu baştan sona tarayarak (table scan / full access) veya  ilgili kolonlar üzerinde veriye erişimi hızlandırmak için oluşturulan index sayfalarını okuyarak (index seek / index scan) erişebilmektedir. Çoğu durumda index sayfalarının okunmasıyla veriye erişim çok daha hızlı gerçekleştirilmektedir. Bu sebeple veritabanı geliştiricileri veya veritabanı yöneticileri optimize etmek istedikleri sorguları inceleyerek belirli kolonlara indexler oluşturarak sorgu sürelerini azaltmayı hedeflemektedirler.

İndex oluşturulan kolonlar SQL sorgusunun WHERE kısmında yalın haliyle kullanıldığında (herhangi bir function veya expression içerisinde kullanılmadığında), ilgili sistemin optimizerı oluşturulan indexin sayfalarından okuma yaparak veriye hızlıca erişebilir. Ancak index oluşturulan kolonlar WHERE koşulu içerisinde yalın haliyle kullanılmayıp, örneğin bir fonksiyon içerisinde kullanıldıysa, ilgili optimizer veriye erişebilmek için var olan indexi kullanamaz hale gelir.

Genellikle veritabanı geliştiricilerinin başına gelen ve “Neden oluşturmuş olduğum index optimizer tarafından kullanılmıyor?” sorusunun muhtemel yanıtlarından birisi yukarıda bahsedilen durumdur. Oracle, böyle bir durumla karşılaştığınızda sizlere index oluşturulmak istenilen kolonu yalın haliyle indexleme imkanının yanında bir de kullanılan fonksiyon ile beraber ayrıca index oluşturma imkanını da sunmaktadır. Bu şekilde oluşturulan index türüne Oracle’da Function-Based İndex adı verilmektedir. Function-Based İndex‘ler vasıtasıyla tablolara ait kolonlar Oracle fonksiyonları ile beraber indexlenebilmektedir. Genel olarak anlattığımız konuyu bir de örnekle inceleyelim:

Aşağıda Oracle SQL Developer aracı kullanılarak bir SQL sorgusu çalıştırılmaktadır:

SELECT *
FROM grade,
  student,
  instructor,
  zipcode
WHERE UPPER(grade_type_code) = 'PJ';

Yukarıdaki SQL sorgusunda course, instructor, zipcode ve grade tabloları cross join olacak şekilde bağlanmış ve sorgunun WHERE filtresi kısmında grade_type_code değeri ‘PJ’ olan kayıtlar getirilmek istenmiştir. Ancak ilgili tabloda tutulan değerlerin küçük/büyük harflerle birlikte tutulabileceği göz önüne alınarak grade_type_code kolonu UPPER fonksiyonu ile beraber kullanılarak her çeşit tutulabilen değerlerin getirilmesi garanti altına alınmıştır.

Bu şekilde oluşturulan bir sorgu için sadece grade_type_code kolonu üzerine DENEME_1 isminde bir index oluşturalım:

CREATE INDEX DENEME_1 ON GRADE (GRADE_TYPE_CODE);

Ardından sorgumuzun explain planını inceleyerek Oracle optimizerının DENEME_1 ismindeki indexi kullanıp kullanmadığına bakalım:

FB_index_1

Explain Plan çıktısından görülebileceği gibi Oracle optimizerı grade tablosuna DENEME_1 index sayfalarını okuyarak değil, FULL TABLE ACCESS yöntemini kullanarak bütün tabloyu baştan sona okumayı tercih etmiş gözüküyor. grade_type_code kolonunda index oluşturulmasına rağmen bu yöntemi seçmesi ve indexi kullanamamasının sebebi, grade_type_code kolonunun UPPER fonksiyonu içerisinde kullanılmış olmasıdır.

Bu durumda Oracle Function-Based İndex oluşturularak bu sorunun üstesinden gelinmesi sağlanabilir. Aynı sorguyu bir de aşağıdaki DENEME_2 isminde bir Function-Based Index oluşturarak çalıştıralım ve explain planını inceleyelim:

CREATE INDEX DENEME_2 ON GRADE (UPPER(GRADE_TYPE_CODE));

Şu an grade tablosundaki grade_type_code kolonu üzerinde hem DENEME_1 isminde bir normal index bulunmakta, hem de DENEME_2 isminde bir function based index bulunmaktadır. Sorgunun tekrar çalıştırılmış ve explain planının oluşturulmuş hali aşağıdaki gibi olacaktır:

FB_index_2

Görüldüğü gibi Oracle SQL optimizerı DENEME_2 ismindeki function-based indexi kullanarak veriye erişmiş durumdadır. Aşağıda her iki durumda oluşturulan explain planların karşılaştırılması verilmiştir:

FB_index_3

Oracle veritabanlarında kullanılan sorgular için funciton-based index oluşturulması görüldüğü gibi oldukça basit bir işlemden ibarettir. Normal bir index oluşturur gibi indexe bir isim verilmekte, hangi tablonun hangi kolonu üzerinde index oluşturulacağı belirtilmekte, farklı olarak sadece bu kolonu ilgili fonksiyon ismi ile beraber indexleneceği bilgisi verilmektedir. İşinize yaraması dileklerimle bir sonraki yazımızda görüşmek üzere…

Yazar: Abdullah ALTINTAŞ

Yorum Yaz