Sorgu Optimizasyonu (Query Optimization) – Sorgularımızı nasıl daha iyi hale getirebiliriz ?

Temel olarak SQL diline hakim olduğumuzda istediğimiz tablolardan istediğimiz verileri çekebilecek hale gelmiş oluyoruz. Aynı zamanda komut ve operatörlere daha fazla hakim olmaya başladığımızda farklı komutların aynı çıktıları bizlere verebileceğini de görmüş oluyoruz. Peki ya farklı komutların server tarafında yaptıkları işler tamamen aynı mı ? Hepsi aynı düzeyde mi performans veriyor ? Sunucuya gönderdiğimiz sorguları nasıl daha yüksek performanslı hale getirebiliriz ? Eğer sizlerin de bu tarz soruları varsa bu konuya biraz değinmenin vakti geldi.

SQL Sorgu Optimizasyonunun Amacı Nedir ?

SQL sorgu optimizasyonunun başlıca amaçları şunlardır ;

Yanıt Sürelerini Azaltmak : Amaç yanıt süresini azaltarak performansı arttırmaktır. Daha iyi bir kullanıcı deneyimi için kullanıcılara daha hızlı sonuçlar getirilmelidir.

Geliştirilmiş Verim : Gerekli tüm verileri getirmek için erişilecek kaynak sayısı en aza indirilmelidir. Belirli bir sorguda getirilecek satır sayısı, en az sayıda kaynak kullanılacak şekilde olmalıdır.

Sorgu performansını analiz etmeye yönelik metrikler nelerdir ?

Bu başlıkta performansımızı analiz ederken dikkat edeceğimiz unsurları ve ne anlama geldiklerini inceleyeceğiz.

1-) Execution Time : Sorgu performansını analiz etmek için en önemli ve ilk bakılacak metrik sorgunun yürütme süresidir. Execution Time, sorgunun satırları veritabanından döndürmek için geçirdiği süre olarak tanımlanır.

STATISTICS TIME ON komutunu kullanarak sorgunun parse, compile, execution ve completion sürelerini görüntüleyebilirsiniz.

SET STATISTICS TIME ON
SELECT * FROM PERSON.PersonPhone;
Resim - 1 – STATISTICS TIME ON komutunun kullanımı

Parse and Compile Time ( Ayrıştırma ve Derleme Süresi) : Sorgunun sözdizimini kontrol etmek için ve derlemek için geçen süreyi ifade eder.

Completion Time: Sorgunun sonucu döndürdüğü tam zamanı ifade eder.

Bu metrikleri analiz ederek sorgunun performansının analizini yapabilirsiniz.

2 – ) Statistics IO

IO, sorgu çalıştırıldığında okuma yapmak için arabelleklere erişir.

STATISTICS IO ON  komutunu kullanarak sorguyu yürütmek için gerçekleşen fiziksel (physical) ve mantıksal (logical) okumaların sayısını elde edebilirsiniz.  

SET STATISTICS IO ON
SELECT * FROM PERSON.PersonPhone;
Resim - 2 – STATISTICS IO ON komutunun çıktısı

Logical Reads ( Mantıksal Okuma) : Arabellek önbelleğinde gerçekleştirilen okuma sayısı.

Physical Reads (Fiziksel Okuma) : Depolama aygıtında gerçekleştirilen okuma sayısı.

3 – ) Execution Plan

Execution Plan, bir sorgunun yürütülmesindeki ana aşamaları analiz etmenize yardımcı olur. Yürütmenin hangi bölümünün daha fazla zaman aldığını bulabilir ve o bölümü optimize edebilirsiniz.

Resim - 3 – Sorgu çalıştırılması sonrası Execution Plan görüntüsü

Ayrıca sorgu yürütme sırasında gerçekleştirilen alt işlemler için daha ayrıntılı analiz görünümünü imlecinizi üzerine getirerek görebilirsiniz.

Resim - 4 – Clustered Index Scan kısmının detaylı görüntüsü

Sorgu Optimizasyon Teknikleri (Query Optimization Techniques)

Şimdiye kadar bir sorgunun nasıl yürütüldüğünü ve sorgu performasını nasıl analiz edebileceğimizi, nelerden yararlanabileceğimizi gördük. Şimdi sıra sorgu performansını nasıl optimize edeğimizi öğrenmekte.

İndeksleme (Indexing)

SQL Server’ da, bir sorgu çalıştırdığımızda bir yürütme planı oluşur. Yürütme planı bu bölümde eğer performansı optimize etmek için oluşturulabilecek herhangi bir indeks varsa uyarı verir. Bu uyarı ile mevcut tablonun hangi sütunlarının indekslenmesi gerektiği konusunda bilgi verir.

Resim - 5 – Execution Plan içerisinde serverın bize verdiği missing index uyarısı

Yürütme planında Index Scan bölümüne sağ tıklayıp Missing Index Details… seçeneğine tıklarsanız açılan pencerede yorum satırlarını silerek kolayca indeks tanımlaması yapabilirsiniz.

Resim - 6 – Index Scan bölümünden missing index details kısmına giriş

Gerekli indeks tanımlamalarını yaptıktan sonra sunucu sorguların çıktılarını çok daha hızlı bir şekilde sizlere sunacaktır.

Seçim ( Selection)

Sorgulama yaparken kullanılan SELECT  *  ifadesiyle birlikte tüm veritabanı tarandığı için çok verimsizdir. Bunun yerine sütunlar belirtilirse çok daha yüksek performans ortaya çıkacaktır.

SET STATISTICS TIME ON
SELECT * FROM PERSON.PersonPhone
Resim - 7 – SELECT komutunun ” * ” ile kullanımı sonucu execution time çıktısı
SET STATISTICS TIME ON 
SELECT BusinessEntityID, PhoneNumber,PhoneNumberTypeID, ModifiedDate FROM PERSON.PersonPhone;
Resim - 8 – SELECT komutunun sütunlar belirtilerek kullanımı sonucu execution time çıktısı

DISTINCT Kullanımından Kaçınma

SQL Server’ da DISTINCT komutu tekrar eden verileri sorgu sonucunda tekil olarak gösterir. Bu işlemi yapmak için ilgili satırları bir araya toplar ve sonra onları kaldırır. Fakat yapılan bu işlem performansı kötü etkilemektedir.

SET STATISTICS TIME ON 
SELECT DISTINCT FirstName, LastName FROM Person.Person ;
Resim - 9 – DISTINCT komutu kullanılarak yapılan sorgunun execution çıktısı
SET STATISTICS TIME ON 
SELECT FirstName, LastName FROM Person.Person ;
Resim - 10 – DISTINCT komutu kullanılmadan yapılan sorgunun execution çıktısı

Örnekte görüldüğü üzere execution sürelerine bakarak DISTINCT komutunun performansı olumsuz etkilediğini söyleyebiliriz.

INNER JOIN ve WHERE kullanımları

Birden fazla tablodan veri çekmek istediğimizde WHERE komutu yerine INNER JOIN komutunu kullanarak çok daha yüksek performansa ulaşabilirsiniz.

SET STATISTICS TIME ON 
SELECT A.FirstName, A.LastName, P.PhoneNumber FROM Person.Person AS A,
Person.PersonPhone AS P 
WHERE P.BusinessEntityID = A.BusinessEntityID;
Resim – 11 – Sorgunun WHERE tümleci kullanarak çalıştırılması sonucu execution time.
SET STATISTICS TIME ON 
SELECT A.FirstName, A.LastName, P.PhoneNumber FROM Person.Person AS A
INNER JOIN Person.PersonPhone AS P 
ON P.BusinessEntityID = A.BusinessEntityID;
Resim – 12 – Sorgunun INNER JOIN kullanılarak çalıştırılması sonucu execution time.

 

Bu yazıda indeks çalışmasından ve bazı komut ve operatörlerin kullanım farklarından bahsettik. Bu yöntemleri kullanarak sorgu performasınızı çok daha iyi hale getirebilirsiniz. Sonraki yazılarda görüşmek üzere.

Leave a Reply

Your email address will not be published. Required fields are marked *