Temel SQL Tuning (Ders-2)

Merhaba arkadaşlar bu yazımda SQL Tuning metotlarından bahsedeceğim. Kısaca SQL Tuning, çalıştıdığımız işlerin daha performanslı çalışmasını sağlamaktır. Bunu yaparken amacımız milyar satırlık bir tablodan istediğimiz veriyi en hızlı şekilde çekmek ve sisteme minimum yük bindirmektir şeklinde bir örnekle açıklayabiliriz. Tabi performans arttırma işlemleri sadece yazılan scripte bağlı değildir. Kullanılan sistem, sistem mimarisi de çok büyük etkenlerdir fakat o kısımlara girmeden bir developer olarak yazdığımız sorguları en optimum şekilde nasıl düzenleyebiliriz onlardan bahsedeceğim.

Diyelim ki milyonluk tablolardan data çekmek istiyoruz. İlk kullanmamız gereken obje indexlerdir. Indexlerin temel mantığı çalışılan işi hızlandırmaktır. Eğer çalıştığımız bu tabloda index yoksa önceki yazılarımda da bahsettiğim gibi oracle istediğimiz dataları bize döndürmek için tüm tabloyu tarar , bu da çok fazla maliyet demektir. Indexlerin çalışma prensibini önceki yazılarımda bulabilirsiniz burada tekrar değinmeyeceğim. Burada dikkat etmemiz gereken nokta çekmek istediğimiz datanın tablodaki tüm verinin %15 ini geçmemesi gerektiğidir. Buna da şu şekilde bakabiliriz ;

SELECT ((SELECT COUNT(1) FROM ([ÇalıştırmakİstediğiniSorgu]))*100) / (SELECT COUNT(1) FROM [ÇalışmakİstediğinizTablo]) FROM DUAL;

Bu sorgu sonucunda çıkan değer 15 ve altındaysa bu sorguda mutlaka index kullanmamız gerektiğini bilmeliyiz. Bazı durumlarda tabloda index olsa bile ve çekmek istediğimiz data tablonun %15 inden az ise indexleri kullanamayız. Bu durumlara sırasıyla değinelim;

1-) Eşit Değildir(<>,!=) Operatörünü Kullanmak

Sorgumuzda where ifadesinden sonra kullandığımız eşit değil operatörleri indexleri kullanmamıza engel olur. Aslında çok basit bir mantığı var. Eşit değildir operatörleri istediğimiz datanın tam tersi durumları arayacağı için tablonun %15 sınırını aşmış oluyoruz. Yine de bu operatörleri kullanmamız gereken durumlarda subquery(alt sorgu) yöntemi ile sorgumuzu düzenleyebiliriz.

2-) IS NOT NULL/ IS NULL Operatörlerini Kullanmak

Indexli bir tabloda indexi kullanabilmek için indexin tanımlı olduğu kolonda null alan bulunmaması gerekmektedir. Diyelim ki indexli kolonda null alanlar var ve bizim de indexi kullanmamız gerekiyor. Bu durumda o kolondaki null alanları herhangi bir değerle doldurmamız gerekiyor. Bu genelde -99 olur. Yine de dolduramadığımızı farz edelim. O zaman tabloda tanımlanan index function based index türünde olmalıdır. Yani index, create index[indexadi] on [tabloadi] ([nvl(kolonadi,-99)]) şeklinde tanımlanmalıdır. Sorgusu da select………. where nvl(kolonadi,-99) şeklinde olmalıdır.,

3-) Veri Tiplerinin Uyuşmazlığı

Diyelim ki number veri tipine sahip bir kolondan veri çekiyoruz. Ama sorgumuz select…….. where kolonadi=’1′ şeklinde. Bu durumda biz görmesek bile Oracle arka planda bu sorguyu select…….. where to_char(kolonadi) =’1′ şeklinde çevirmektedir. Bu durum char dan number a doğru da olabilir. Bu durumda performans kaybına sebep olacaktır.

Son olarak son çalışan işler arasında performans açısından analiz etmek isterseniz aşağıdaki kodu kullanabilirsiniz.

select * from ( SELECT parsing_schema_name "Owner",
         last_load_time,
         last_active_time,
         executions,
         rows_processed,
         ROUND (rows_processed / executions) AS "RowCount",
         ROUND (cpu_time / executions) AS "CpuTimeCount",
         ROUND (buffer_gets / executions) AS "MemoryCount",
         ROUND (disk_reads / executions) AS "DiskReadCount",
         executions "# of Executions",
         (elapsed_time / executions) / 1000000 AS "TimeSpend sec.",
         DBMS_LOB.SUBSTR (SQL_FULLTEXT, 4000, 1) AS SqlFullText
    FROM gv$sql
   WHERE executions > 0
     AND parsing_schema_name = '&schema_name'
     AND module like '%&module_name%'
     AND TRUNC (last_active_time) = TRUNC (SYSDATE)
ORDER BY 7 DESC)
where rownum <21;    

Yukarıdaki sorguda çalışan işler çalışma süreleri bazından sıralandı. Diskteki yüküne göre sıralamak isterseniz Order By dan sonra 7 yerine 8 yazabilirsiniz. Ayrıca bu sorgu son 20 işi döndürmek üzere düzenlendi. Daha fazla kayıt görmek isterseniz rownum dan önceki değeri değiştirebilirsiniz. Module adını da bilmiyorsanız SELECT DISTINCT MODULE FROM V$SESSION sorgusu ile bakabilirsiniz.

Bu yazımda anlatacaklarım bu kadardı. Umarım faydalı olmuştur, herkese iyi çalışmalar dilerim.

Halil İbrahim ARSLAN

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir