SQL Server‘da yazılan sorguların performanslı bir şekilde çalışmalarını sağlamak için kullanılan çeşitli seçenekler bulunmaktadır. Bu seçenekleri kullanarak daha optimize sorgular yazılabilmekte ve Execution Plan‘lar incelenerek yazılan sorguların karşılaştırmaları yapılabilmektedir. Bu yazımızda bu seçeneklerden biri olan Fast N seçeneğini ele alacağız.
SQL Server’da Execution Plan’a müdahale ederken kullanılan faydalı kullanımlardan biri de Fast N seçeneğidir. Sıkça karıştırılan bu operatörü kullanarak, SQL Server’ın sorgu sonucunda gösterilecek olan sonuç kümesinin içinde N (N pozitif bir sayı) tane kaydı en hızlı getirecek şekilde Execution Planı optimize etmesini sağlayabiliriz. Fakat dikkat edilmesi gereken nokta burada verilen N pozitif bir sayı olmakla beraber gösterilecek kayıt sayısı ile alakalı değildir. Şöyle ki sorgumuzun sonucunda 1000 tane kayıt döndüğü durumda bu 1000 kaydın ilk 10 tanesinin olabilecek en hızlı bir şekilde ekrana getirilmesi ve kalan 990 tanesinin de ilk 10 tane hızlı bir şekilde gösterildikten sonra normal bir şekilde ekranda gösterilmesi isteniyorsa SQL Server’da bulunan Fast N seçeneği kullanılarak bu işlem çok daha performanslı bir şekilde gerçekleştirilebilmektedir. Ancak bu operatör çoğu zaman kayıt kümesinin N tane kayıt ile sınırlandırılacağı olarak düşünülmektedir. Bu yanılgıya düşülmemeli ve buna göre sorgular yazılmalıdır.
Şimdi Fast N operatörünün nasıl kullanıldığını bir örnek üzerinde görelim. İlk sorgumuzda Fast N operatörünü kullanmadan Execution Planımızı inceleyelim daha sonra aynı sorgumuzu Fast N operatörünü kullanarak SQL Server’ın kullanacağı Execution Planı inceleyelim ve karşılaştıralım.
Yukarıdaki sorgumuzda Production.Product tablosu ile Sales.SalesOrderDetail tablosunu Inner Join ile birleştirdik. Şimdi Execution Planımızı inceleyelim.
Yukarıdaki resimde sorgumuzun Execution planını incelediğimizde Sales.SalesOrderDetail tablosundaki veriler Clustered Index Scan işlemi ile okunup Compute Scalar operatörü ile tabloda bulunan Computed Column (Hesaplanmış Sütun) değeri hesaplanarak elde edilen sonuç kümesi ile Production.Product tablosu üzerinde yapılan Clustered Index Scan işleminin sonucu ile Hash Match Join işlemi ile birleştirilmiştir. Şimdi sorgumuza Fast 5 değerini ekleyerek SQL Server’a ilk 5 kaydın en hızlı geleceği şekilde sorgumuzun Execution Planını optimize ettirelim ve çıkan Execution Planı inceleyelim.
Yukarıdaki sorgumuza farklı olarak sadece option(fast 5) operatörünü ekledikten sonra şimdi Execution Planımızdaki değişiklikleri inceleyelim.
Yukarıdaki resimdeki Execution Planımızı incelediğimizde öncekine benzer olarak Sales.SalesOrderDetail tablosundaki veriler Clustered Index Scan işlemi ile okunup Compute Scalar operatörü ile tabloda bulunan Computed Column (Hesaplanmış Sütun) değeri hesaplanarak elde edilen sonuç kümesi önceki Execution planımızdan farklı olarak Production.Product tablosu üzerinde Clustered Index Seek işlemi yapılmış ve elde edilen sonuçlar Nested Loop Join operatörü ile birleştirilmiştir.
Aslında iki Execution Planımızda farklı olan kısımları incelediğimizde ilk planda Production.Product tablosu üzerinde Clustered Index Scan işlemi yapılmıştır. SQL Server’ın bunu seçmesinin sebebi bu tablodaki tüm kayıtlara erişmemiz gerektiğinden dolayıdır ve bu sebeple SQL Server Scan işlemini daha hızlı sonuçlandıracağı için Clustered Index Scan işlemini tercih etmiştir. Fakat Fast 5 seçeneğini kullandığımız sorgumuzda Product tablosu üzerinde Clustered Index Scan yerine Clustered Index Seek işlemi tercih edilmiştir. Bunun sebebi ise Fast 5 operatörünü kullandığımız için SQL Server ilk 5 kaydı en hızlı getirmek için Clustered Index Seek işlemini tercih etmesidir. Genel kanı olarak Seek işleminin Scan işlemine göre daha iyi olduğu düşünülse bile Seek işleminin yapıldığı veri kümesi büyüdükçe sorgumuzun performansı da düşecektir. Aynı zamanda iki Execution Plan arasındaki bir diğer fark ise seçilen Join tipidir. İlkinde Hash Match Join seçilmesinin sebebi sıralı olmayan iki büyük veri kümesinin birleştirilmesidir. Fakat ikinci Execution planda ise Nested Loop Join seçilmiştir. Bunun sebebi ise Fast 5 ile yaptığımız optimizasyonda SQL Server beş kaydın okunması senaryosuna göre sorgumuzun Execution planını optimize etmiş ve Sales.SalesOrderDetail gibi büyük bir tablo ile 5 kayıt içeren bir veri kümesinin birleştirilmesinde doğal olarak Nested Loop Join işlemini seçmiştir.
Fakat Fast 5 seçeneği yerine sonuç kümesine yakın bir değer kullanmış olsaydık SQL Server Execution Planı değiştirmeyecekti. Örneğin aynı sorgumuzu Fast 1000 olarak çalıştırıp Execution planını inceleyelim.
Fast N operatörü özellikle bazı durumlarda sorgu performansını beklenenden fazla artırmaktadır. Örneğin sorgularımızda top kullandığımızda gelen sonuç kümesinin sıralı olması önemli değilse ve bu sebeple order by operatörünü kullanmıyorsak Fast N operatörü performans açısından yararlı olacaktır. Şimdi bunu bir örnek üzerinde görelim.
Yukarıdaki iki sorgumuzdan da 5 kayıt gelecektir. Şimdi sorgularımızı çalıştırdıktan sonra sonuçları IO açısından değerlendirelim.
Yukarıdaki resimde gösterilen IO sonuçlarını incelediğimizde sadece Top 5 ile çalıştırdığımız sorgumuzdaki logical read değeri 468 iken Top 5 operatörünü aynı yazanda Fast 5 ile kullandığımızda ise logical read değerimiz 10 olacaktır.
Bu yazımızda SQL Server’da performans açısından bazı durumlarda faydalı olabilecek bir seçenek olan Fast N operatörünü ele aldık. Umarım faydalı olur. Bir sonraki yazımızda görüşmek dileğiyle.
Keyifli okumalar…
Yazar: Abdullah ALTINTAŞ