SQL Server’ın performans için kullandığı en önemli özelliklerinden bir tanesi, bir sorgu ilk defa çalıştırıldığında bu sorguya ait maliyeti en düşük olan Execution planın oluşturulması ve aynı sorgunun bir daha çalıştırıldığında tekrar Execution plan hesaplaması yapmadan, daha önce oluşturulmuş Execution planın kullanılmasıdır. Bu durum genelde SQL Server’ı hesaplama yükünden kurtardığı için sorgularımızın sonraki çalıştırılmasında daha hızlı çalışabilmesini sağlamaktadır. Execution planın bir sonraki sorgu için saklanması genelde iyi bir yöntem olmasına rağmen özellikle Stored Procedure gibi yapılarda farklı parametre değerleri için aynı Execution planın kullanılması özellikle veri dağılımının düzgün olmadığı durumlarda performans problemine sebep olabilmektedir. Örneğin sattığımız ürünlerin bilgilerini tuttuğumuz bir tablomuz olduğunu düşünelim. Tablomuzda 100 numaralı ürüne ait birkaç kayıt varken, çok satılan bir ürün olan 70 numaralı ürün için çok fazla kayıt olduğunu düşünelim. Tablodaki kayıt sayısına da bağlı olarak, eğer Execution planımız oluştuğunda 100 numaralı ürüne göre oluşturulursa muhtemelen Index Seek işlemi tercih edilirken, 70 numaralı ürün için Index Scan işlemi tercih edilecektir. İşte böyle durumlarda ilk kullanılan sorgu için oluşturulacak olan Execution planın saklanıp diğer tüm parametreler için kullanılması SQL Server tarafından sorgumuzun performansının düşmesine sebep olacaktır. Bu soruna literatürde Parameter Sniffing denilmektedir.
Varsayılan olarak SQL Server’da daha sonra kullanılmak üzere Execution planlar saklanır. Fakat Execution planın saklanmasını istemediğimiz durumlarda sorgularımıza RECOMPILE seçeneği eklenebilir. Bu seçenek ile sorgumuz her çalıştırıldığında en uygun Execution plan yeniden hesaplanıp oluşturulacaktır. Şimdi RECOMPILE seçeneğinin kullanabileceği durumu örnek üzerinde görelim.
DECLARE @ProductId INT
SET @ProductId = 870
SELECT SalesOrderID
,ProductID
,OrderQty
FROM Sales.SalesOrderDetail
WHERE ProductID = @ProductId
SET @ProductId = 903
SELECT SalesOrderID
,ProductID
,OrderQty
FROM Sales.SalesOrderDetail
WHERE ProductID = @ProductId

Yukarıdaki örneğimizde ilk sorgumuzdan 4688 tane kayıt dönerken, ikinci sorgumuzdan 14 tane kayıt dönmektedir. Fakat dikkat ederseniz her iki sorgunun da Execution planı aynıdır. Şimdi her sorgumuza RECOMPILE seçeneğini ekleyerek Execution planımızı tekrar inceleyelim.
DECLARE @ProductId INT
SET @ProductId = 870
SELECT SalesOrderID
,ProductID
,OrderQty
FROM Sales.SalesOrderDetail
WHERE ProductID = @ProductId
OPTION(RECOMPILE)
SET @ProductId = 903
SELECT SalesOrderID
,ProductID
,OrderQty
FROM Sales.SalesOrderDetail
WHERE ProductID = @ProductId
OPTION(RECOMPILE)

Yukarıda görüldüğü üzere her iki sorgumuza da RECOMPILE seçeneğini ekleyerek çalıştırdığımızda her iki sorgumuz için de sorgu çalıştırılmadan önce uygun Execution plan hesaplanmış ve bu Execution plan kullanılmıştır. İkinci sorgumuzda veri miktarı az olduğu için ilk sorgudan farklı olarak Clustered Index Scan işlemi tercih edilmemiş bunun yerine ProductId kolonu üzerinde oluşturulan indeks ile Key Lookup işlemi tercih edilmiştir. Bu iki sorgunun birbirine maliyetine baktığımızda da ilk sorgunun maliyeti %95 iken ikinci sorgunun maliyeti %5 olarak hesaplanmıştır.
RECOMPILE seçeneğini kullandığımızda gördüğünüz gibi SQL Server ikinci çalıştırılan sorgumuz için daha uygun olan bir Execution plan seçmiştir. RECOMPILE seçeneğinin yukarıdaki örnek durumumuzda kullanımı doğru Execution planının seçilip, sorgumuzun daha performanslı çalışmasını sağlamış olsa bile özellikle sık kullanılan karmaşık sorgularda kullanılan RECOMPILE seçeneği ile her çağrıldığında SQL Server bir hesaplama yapacak ve bu durum SQL Server’a ekstra CPU yükü getirecektir. Yani diğer bir değişle RECOMPILE seçeneğini kullanırken dikkatli olmamız gerekmektedir. Bu seçenek her sorgumuza değil sadece gerçekten gerekli olan sorgularımıza eklenmesi durumunda faydalı olacaktır.
Bu makalede execution yapılarında görülen RECOMPILE Query Hint ifadesine değinmiş olduk. Başka bir makalede görüşmek dileğiyle..
Gündüzün iki tarafında ve gecenin (gündüze) yakın saatlerinde namazı kıl. Şüphesiz iyilikler, kötülükleri giderir. Bu, öğüt alanlara bir öğüttür. Hud Suresi, 114. Ayet