SQL Sorgularının I/O İstatistikleri Nasıl İncelenir

SQL sorgularımızda büyük bir performans ölçütü olan IO değerlerini (disk ve bellek kullanımı) görmek istediğimizde SQL Server tarafından bize sunulan basit bir komut olan “SET STATISTICS IO ON/OFF” ile istatiksel verilere rahatlıkla ulaşabiliriz.

Örnek kullanım için 5 milyon satırlık bir tablo oluşturdum

Resim 1

Tablomuzda 3 kolondan oluşmakta ve rastgele verilerden oluşmaktadır.

Resim 2

“SET STATISTICS IO ON” diyerek bağlantımız için istatistiksel bilgilerin gelmesini istiyoruz. Burada unutmamız gereken bu komut sadece açtığımız bağlantıda geçerli olacaktır. New Query diyerek yeni bir bağlantı açtığımızda bu komutu yazmadığımız müddetçe bu bilgileri göremeyiz veya “SET STATISTICS IO OFF” demediğimiz sürece bu bilgiler Messages bölümü altında gelecektir.

Resim 3

Tablomuzdan rastgele seçtiğim bir değeri şart olarak koyuyorum ve sorgumu çalıştırıyorum ve Messages sekmesi altındaki verilere baktığımızda aşağıdaki gibi rakamları görüyoruz. Ayrıca şuan tablomuzda herhangi bir index bulunmamaktadır.

Table ‘STATISTICSDEMO’. Scan count 13, logical reads 29850, physical reads 0, page server reads 0, read-ahead reads 29822, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

Yukarda çıkan sonuçlara baktığımızda logical reads değeri için 29850*8=238.800 kilobytes yani 238MB okuma yaptığını görüyoruz.

Resim 4

Aynı sorguyu tekrar çalıştırdığımızda “read-ahead reads”  değerinin 0 olduğunu görüyorum.

Resim 5

Table ‘STATISTICSDEMO’. Scan count 13, logical reads 29850, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

Peki bu değerler ne anlama geliyor kısaca onlardan bahsedeyim

TableTablo ismi
Scan countTablo üzerinde yapılan Scan/Seek sayısı
logical readsCache/Önbellekten okunan sayfa
physical readsDiskten okunan sayfa sayısı
read-ahead readsSorgu için önbelleğe çekilen sayfa sayısı
lob logical readsCache/Önbellekten okunan text, ntext, image, varchar(max), nvarchar(max), varbinary(max)  ve columnstore index içeren sayfalar için yapılan okuma işlemi
lob physical readsDiskten okunan text, ntext, image, varchar(max), nvarchar(max), varbinary(max)  ve columnstore index içeren sayfalar için yapılan okuma işlemi
lob read-ahead readsSorgu için önbelleğe çekilen text, ntext, image, varchar(max), nvarchar(max), varbinary(max)  ve columnstore index içeren sayfalar için yapılan okuma işlemi

Örneğimize geri döndüğümüzde sorgumuzun Execution planını incelediğimizde bize bir index önerisi sunuyor. Burada önerilen her indexi oluşturmak yanlış bir yaklaşım olur çünkü bizim bu tablo üzerindeki iş yüküne göre değil sadece yazdığımız bu sorgu için bir öneri yapmaktadır.

Resim 6

Ama bizim tablomuzda herhangi bir index olmadığından ve şartlı bir sorgumuz olduğundan bu indexi oluşturuyorum

Resim 7

dbcc dropcleanbuffers; komutu ile cache/önbellekteki verileri temizliyorum.

BU KOMUTU CANLI ORTAMLARDA KULLANMAYINIZ 😊

Resim 8

Aynı sorgumuzu tekrar çalıştırdığımızda oluşturduğumuz index sayesinde çok belirgin bir fark ortaya çıktığını görüyoruz.

Table ‘STATISTICSDEMO’. Scan count 1, logical reads 4, physical reads 3, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

Resim 9

Sorgumuzu tekrar çalıştırdığımızda physical reads değerinin düştüğünü görmekteyiz.

Table ‘STATISTICSDEMO’. Scan count 1, logical reads 4, physical reads 0, page server reads 0, read-ahead reads 0, page server read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob page server reads 0, lob read-ahead reads 0, lob page server read-ahead reads 0.

Yukarda çıkan sonuçlara baktığımızda logical reads değeri için 4 page * 8 KB=32 KB okuma yaptığını görüyoruz.

Resim 10

Örneğimizde sadece bir tablo üzerinden işlem yapmamıza rağmen bize verdiği istatistiksel bilgi uzun bir metin halinde vermektedir. Birden fazla tablo kullandığımız durumlarda bu metinler daha karmaşık bir hale gelmektedir.

Örnek olarak aşağıda Logo veri tabanında yazılan bir sorgunun istatistiksel IO verilerini görüyoruz.  Bura da 7 tablo üzerinden işlem yaptığımızı ve karmaşık bir görüntü olduğunu görüyoruz.

Resim 11

https://statisticsparser.com ile bu karmaşık görüntüleri daha okunaklı bir hale getirip çalışmalarımızı yürütebiliriz

Resim 12

Bu yazımda sizlere SQL sorgularını yazarken benim sık kullandığım “SET STATISTICS IO ” komutunun nasıl kullanıldığını hakkında bilgi vermeye çalıştım umarım sizlere de faydalı olmuştur.

Leave a Reply

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