SQL Server Query Hint Kavramı ve Bazı Query Hint’ler

28 Tem by NURULLAH ÇAKIR

SQL Server Query Hint Kavramı ve Bazı Query Hint’ler

Query Hint’ler sorguların sonuna eklenerek sorgunun normal çalışma şeklini değiştirebilirler. Örneğin tek cpu’yu kullanarak çalışan bir sorgunun sonuna maxdop query hint’ini ekleyerek birden fazla cpu üzerinde çalışmasını ya da sorgunun her çalışmada yeniden query plan üretmesini sağlamak için recompile query hint’ini kullanabilirsiniz.

 

Query Hint’i uygulamadan önce yaptığınız işlemin istediğiniz sonucu verdiğinden emin olmanız gerekir. Çünkü query hint kullanarak SQL Server’ı normal davranışından uzaklaştırarak istediğiniz şekilde hareket etmeye zorlamış oluyorsunuz. Makalede belirtilen script’ler microsoft’un sitesinden alınarak AdventureWorks2012 veritabanı üzerinde test edilmiştir.

 

Aşağıda işinize yarayabileceğini düşündüğüm bazı query hint’lerinin açıklamalarını ve örneklerini paylaşıyorum.

 

RECOMPILE Query Hinti:

SQL Server’da stored procedure’ler ve parametreli gelen sorgular ilk kez çalıştığı anda compile edilerek bir query plan üretirler ve sonraki çalışmalarında tekrar compile edilmeden daha önce ürettikleri query plan’ı kullanarak sorgu her çalıştığında tekrar compile etme yükünden kurtulmuş olurlar.

 

Bu davranış şekli çoğu zaman performansı artırır. Fakat tablodaki veri dağılımı dengesizse bazen parameter sniffing’e sebep olur. “Parameter Sniffing” isimli makalede parameter sniffing ile ilgili detayları bulabilirsiniz. Bu yüzden Recompile Query Hint’i ile sorgunun her çalıştığında yeniden query plan üretmesini isteyebilirsiniz. “Parameter Sniffing” isimli makalede recompile örneğini bulabilirsiniz.

 

OPTIMIZE FOR Query Hinti:

Query Plan üretilirken query optimizer’a, Lokal bir değişken için belirli bir değer kullanması için talimat veren query hint’idir. RECOMPILE query hint’i gibi bu query hint’de parameter sniffing’de işimize yarayabilir. “Parameter Sniffing” isimli makalemde bu query hint çeşidi ile de örnek bulabilirsiniz.

 

USE PLAN Query Hinti:

 

Query Plan üretilirken query optimizer’a, bir sorgu için mevcut bir query plan kullanması için talimat veren query hint’idir.

 

Eğer çalışma süresinin uzun olduğunu ve yanlış query plan ile çalıştığını düşündüğünüz sorgularınız varsa ve sorgunun daha hızlı çalışabilmesi için gerekli bir query plan olduğunu biliyorsanız bu query hint’ini kullanabilirsiniz.

 

Ama benim tavsiyem bu işi sql server’a bırakmanız ve istatistiklerinizi güncel tutmanızdır. İstatistikler hakkında detaylı bilgi almak için “SQL Server’da İstatistik Kavramı ve Performansa Etkisi” isimli makaleyi okumak isteyebilirsiniz.

 

Yinede ben USE PLAN Query Hint’ini kullanmak istiyorum diyorsanız aşağıdaki linkte nasıl kullanacağınızla ilgili detaylar bulabilirsiniz.

 

https://technet.microsoft.com/en-us/library/ms186954(v=sql.105).aspx

 

 

PARAMETERIZATION Query Hinti:

 

Veritabanında parameterization set ettiğimizde bazı sorguların davranış şekli değişir. Template plan guide ile spesifik sorgular için veritabanı seviyesinde set edilen parameterization şeklini değiştirebiliriz.

 

Template Plan Guide için,

 

 “sp_create_plan_guide Sistem Stored Procedure’ü ile Sorgularınızın Performansını Artırın” isimli makaleyi,

 

 

Parameterization için,

 

 “Optimize for ad hoc workloads ve Parameterization” isimli makalemi okumak isteyebilirsiniz.

 

 

MERGE JOIN Query Hinti:

 

Aşağıdaki örnekte join işlemini MERGE JOIN yapmaya zorlayan bir query hint’i kullanılmış. SQL Server’da join işlemleri ile ilgili detaylı bilgi almak için “SQL Server’da Join Türleri” ve “SQL Server Execution Plan’daki JOIN Türleri” isimli makalelerden faydalanabilirsiniz.

SELECT *  
FROM Sales.Customer AS c 
INNER JOIN Sales.CustomerAddress AS ca ON c.CustomerID = ca.CustomerID 
WHERE TerritoryID = 5 
OPTION (MERGE JOIN); 
GO   

 

 

MAXRECURSION Query Hinti:

 

MAXRECURSION Query Hinti kötü tasarlanmış bir CTE(Common Table Expression)’nin sonsuz döngüye girmesini engeller. CTE(Common Table Expression) hakkında detaylı bilgi almak için “Common Table Expression(CTE)” isimli makaleyi okumak isteyebilirsiniz.

 

Aşağıdaki örnekte sınırsız döngüye giren bir CTE oluşturulup arkasından MAXRECURSION query hint’i kullanılarak maksimum döngü sayısını 2 olarak set ediyoruz.

 

–Sonsuz bir döngü oluşturan CTE

WITH cte (CustomerID, PersonID, StoreID) AS 
( 
    SELECT CustomerID, PersonID, StoreID 
    FROM Sales.Customer 
    WHERE PersonID IS NOT NULL 
  UNION ALL 
    SELECT cte.CustomerID, cte.PersonID, cte.StoreID 
    FROM cte  
    JOIN  Sales.Customer AS e  
        ON cte.PersonID = e.CustomerID 
) 
--CTE'yi kullan ve MAXRECURSION query hint'ini kullanan sorgu
SELECT CustomerID, PersonID, StoreID 
FROM cte 
OPTION (MAXRECURSION 2); 
GO 

 

 

Sorguyu veritabanında çalıştırdığımda 2 kere loop’a girdikten sonra aşağıdaki gibi bir hata ile script’i sonlandırdı.

 

Msg 530, Level 16, State 1, Line 1

The statement terminated. The maximum recursion 2 has been exhausted before statement completion.

 

 

Sorgudaki OPTION(MAXRECURSION 2)  hint’ini kaldırdığınızda hata şekli aşağıdaki gibi oldu. SQL Server 2014 üzerinde bu testi gerçekleştirdim. 100 kere loop’a girdikten sonra SQL Server otomatik olarak script’i durdurdu.

 

Msg 530, Level 16, State 1, Line 1

The statement terminated. The maximum recursion 100 has been exhausted before statement completion.

 

 

MAXDOP Query Hinti:

 

Sorgunun sonuna OPTION(MAXDOP 2) hint’ini koyarak, maxdop ayarı instance üzerinde ne seviyede ayarlanmış olursa olsun bu sorgunun 2 core’u kullanarak çalışması gerektiğini belirtmiş olduk.

 

Özellikle iş yükü fazla olan sorgular için kullanmakta faydalı olacak bir query hint’idir.

 

Aşağıdaki şekilde kullanabilirsiniz.

 

SELECT ProductID, OrderQty, SUM(LineTotal) AS Total FROM Sales.SalesOrderDetail
WHERE UnitPrice < $5.00 GROUP BY ProductID, OrderQty
ORDER BY ProductID, OrderQty OPTION (MAXDOP 2); GO

 

 

FORCE INDEX Query Hinti:

 

SQL Server’da bir sorguya şu index’i kullanarak çalış demek için bu hint’i kullanırız. Aslında SQL Server hemen hemen her zaman en iyi seçimi yapar. Bu yüzden istatistiklerinizi güncel tutup, index’lerini düzenli olarak rebuild-reorganize yapıyorsanız bu hint’i kullanmanız genelde sizi hızlandırmaktan çok yavaşlatacaktır.

 

İstatistikler ve index’ler hakkında aşağıdaki makaleleri okumanızı tavsiye ederim.

 

SQL Server’da Index Kavramı ve Performansa Etkisi“,

SQL Server’da İstatistik Kavramı ve Performansa Etkisi

 

Aşağıdaki select ifadesinin aşağıdaki ekrandaki kutucuğa tıklayarak execution plan’ını çıkaralım. Gördüğünüz gibi normal şartlar altında aşağıdaki gibi Clustred Index Scan işlemi gerçekleşiyor.

 

USE AdventureWorks2014Yeni
GO
SELECT *
FROM Person.Person
GO

 

 

 

Sorguya aşağıdaki gibi bir hint ekleyelim. Gördüğünüz gibi belirttiğimiz Index’i kullandı ve daha sonra ihtiyaç duyalan kayıtları getirmek için Key Lookup yapmak durumunda kaldı.

 

 

 

Kullanımını çok ender durumlarda lazım olabileceği için göstermek istedim fakat gerçekten gerekmedikçe kullanmak daha öncede belirttiğim gibi performansınızı azaltacaktır.

Loading

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir