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
Tablomuzda 3 kolondan oluşmakta ve rastgele verilerden oluşmaktadır.
“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.
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.
Aynı sorguyu tekrar çalıştırdığımızda “read-ahead reads” değerinin 0 olduğunu görüyorum.
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
Table | Tablo ismi |
Scan count | Tablo üzerinde yapılan Scan/Seek sayısı |
logical reads | Cache/Önbellekten okunan sayfa |
physical reads | Diskten okunan sayfa sayısı |
read-ahead reads | Sorgu için önbelleğe çekilen sayfa sayısı |
lob logical reads | Cache/Ö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 reads | Diskten 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 reads | Sorgu 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.
Ama bizim tablomuzda herhangi bir index olmadığından ve şartlı bir sorgumuz olduğundan bu indexi oluşturuyorum
dbcc dropcleanbuffers; komutu ile cache/önbellekteki verileri temizliyorum.
BU KOMUTU CANLI ORTAMLARDA KULLANMAYINIZ 😊
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.
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.
Ö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.
https://statisticsparser.com ile bu karmaşık görüntüleri daha okunaklı bir hale getirip çalışmalarımızı yürütebiliriz
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.