Bir hint (ipucu) tavsiye ediyorum! (Parametre değerleriyle başınız beladaysa…)


Hint’leri hiç sevmem. Türkiye şartlarında çoğu durumda fazlaca kolayca kullanılıp etkileri düşünülmediği için…

SQL Server’a gönderdiğiniz bir sorguda hint kullandığınız zaman temel olarak şunu demiş olursunuz: ” Ey optimizer! Sen bilmezsin ben bilirim! Sorgumu iyi analiz edip doğru bir şekilde çalıştıramıyorsun. Bundan sonra HEP şu şekilde çalıştıracaksın!”

Oysa şartlar değişir. Tablodaki veri dağılımı değişebilir. Tabloda yeni indeksler oluşturulabilir. Sizin o emrettiğiniz hint artık geçerli olmayabilir, hatta zarar veriyor olabilir. Eğer tüm hintlerinizi gerekçeleriyle beraber dokümante edip mesela iki ayda bir hala o şekilde bulunmaları doğru mu diye kontrol edecekseniz, eyvallah, o zaman istediğiniz hinti kullanın. Ama biliyorum ki çoğu ortamda hintlerin uzun vadede hala yararlı olduğunun kontrol altında tutulmasını bırakın, hintlerin kullanıldıkları an o sorguya olumlu etkisinin yanısıra başka sorgulara olumsuz etkisinin olup olmadığı bile doğru düzgün test edilmiyor.

Buna rağmen bir özel durum var ki bununla ilgili hint kullanmanız gerekebilir. SQL Server sorguları analiz ederek planlar oluşturur. Bu planları da cache’ler. Yani parametre değerleri farklı olsa da aynı sorgu tekrar geldiğinde (ya da aynı procedure) cache’teki plan kullanılır. Bu çoğu durumda performans açısından iyi bir optimizasyondur. Ama bazen parametre değerleri çok uç noktalara da yayılabilir.

Mesela bir tablonuzda şehir kolonu olduğunu düşünün. Şehir kolonunda değerlerin yüzde 99’u 5-6 şehirde ve her biri en az yüzde 3 falan olarak toplanmış olsun. Kalan yüzde 1’lik veri ise 70 şehre yayılmış olsun. Bu şehirlerden her birinin binde 1’den az verisi var demektir.

İlgili prosedürün henüz hiç bellekte cache’lenmemiş olduğunu düşünün. (Server yeni restart edilmişse mesela…) Prosedür ilk kez çalıştırıldı, yüzde 99 olasılıkla çok karşılaşılan şehirlerden biri gelecek ve o parametre değerine göre optimizasyon yapılacaktır. Bu durumda sorun yoktur. Çünkü zaten sorguların büyük kısmı da bu planın uygun olduğu parametre değerleriyle gelecektir. Ancak bahtsız bedevi misali ilk çalışmasında prosedüre parametre olarak binde birden az görülen şehirlerden biri de gelebilir. Bu çok düşük bir ihtimal olmakla birlikte, parametre değeri böyle gelirse prosedürün planı indekse yönelecektir. Sonraki çalışmalarındaysa hemen hemen her seferinde indeks kullanmanın cinayet gibi olacağı parametre değerleri gelecektir!

Bunu aşmak için sorgunuza şu hinti ekleyebilirsiniz: OPTION (OPTIMIZE FOR (@kent = ‘İstanbul’))

Bu durumda plan oluşturulmasını sağlayan ilk sorguda parametre değeri binde birden az görülen şehirlerden biri de gelse hintiniz yaygın görülen bir şehri esas alarak planın oluşturulmasını sağlayacaktır. Belki bu da ideal olmayabilir ama sorguların hemen hemen tamamı için ideal olup sadece bazı istisnalarda performansta pek hissedilemeyecek bir etki yapar.

Veri değerlerindeki yaygınlıkla paralel olmayan parametre kullanımları varsa, mesela az görülen kolon değerleri sorgularda da az karşılaşılmak yerine mesela sorguların yarısında karşılaşılıyorsa, başka bir seçeneğiniz daha var: Prosedürü yaratırken WITH RECOMPILE diye yaratmak. Bu durumda prosedür her çalıştırıldığında yeniden analiz edilip plan belirlenecektir.

Bu yazı SQL Server içinde yayınlandı ve , , olarak etiketlendi. Kalıcı bağlantıyı yer imlerinize ekleyin.

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s