Where Bloğunda Case Kullanmayın
Keskin bir ifade oldu farkındayım :) O yüzden cümlenin başına “çok zorda kalmadıkça diye” ekleyelim. Kullanmayın deme sebebim ise where bloğunda case kullanımı, istatistikler üzerinden estimated rows hesabı yapılırken yanlış hesaplamalar yapılmasına dolayısıyla da estimate edilecek kayıt sayısının doğru tahminlenememesi anlamına gelmektedir. Bu durumda da Query Plan sağlıklı bir şekilde oluşturulamayacak ve gereksiz IO yapılmasından dolayı performans sıkıntısı ortaya çıkacaktır. Bugünkü yazımda bahsettiğim bu konuyu örnekler ile görüyor olacağız.
Örneklerimde AdventureWork.Person.Address tablosunu kullanıp City kolonu üzerinden sorgular çekeceğim. Bu yüzden ilk olarak City kolonu üzerine bir NonClustered Index oluşturuyorum.
IF not exists (select * from sys.indexes where object_id = OBJECT_ID('Person.Address') AND name = 'IX_1')
create nonclustered index IX_City on Person.Address
(City)
Person.Address tablosuna çekeceğim sorgularda City bilgisi olarak Bothell. Normal şartlarda Bothell için çekilen sorguların Query Planı şu şekilde olmakta.

Şimdi where bloğunda case anahtar kelimesi içeren şöyle bir sorgu yazıyorum.
declare @val1 varchar(10)=NULL
declare @val2 varchar(10)='Bothell'
select * from Person.Address
where City = (case when @val1 is null then @val2
else @val1 end)
Sorguda da gördüğünüz gibi eğer @val1 değişkeni null değil ise city bilgisi olarak bu değişken, eğer null ise city bilgisi olarak @val2 değişkeni kullanılacak. Bu durumda yukarıdaki sorguyu çalıştırdığımda “Bothell” için çalıştırmış olacağım.

Bothell için normal şartlarda Index Seek yaptığını daha önce görmüştük. Oysaki bu sorguda case kullandığım için artık Clustered Index Scan yapılmakta.
Bunun nedeni ise Estimated Rows kısmında gördüğümüz istatistikler üzerinden hesaplanan “tahmini dönecek kayıt sayısı” bilgisinin normalden çok olmasıdır. Aşağıdaki resimde 2 sorgu için tahminlenen kayıt sayılarını görebilirsiniz.

Bu yüzden ilk sorgu için Index Seek yapılmasına karar verilirken, ikinci sorguda dönecek kayıt sayısı olması gerekenden fazla yani yanlış hesaplandığı için Clustered Index Scan yapılmasına karar veriliyor.
İşte bu sebepten dolayı sorguların where bloğunda case kullanımından olabildiğince kaçınmakta fayda olduğunu söyleyebilirim.