SQL Server SARGability Session I

Önemli konulardan biri de performansa dayalı query yazmak için SARGability konularıdır. Burada bunu 3 aşamada ele alacağız bu makale ilk aşamasını kapsayacak ve burada öğrendiğiniz bilgileri mümkün olduğunca query yazımınızda dikkat etmeniz noktalar olarak isminiz gibi bilmeniz sizin faydanıza olacaktır.

Örneklerimiz ile daha net algılayacağız neler anlatmak istediğimizi

Query 1 :

-- Adı 'blade' olan ürünleri listeleyelim...
SELECT Name, ProductNumber 
FROM Production.Product
WHERE Name = 'blade'

Query 1 Execution Plan gözlemlenmesi :

Görüldüğü üzere {6189a1005e4f6dc613b8beb03d694ce50f0902974162d6a7dea944a970422cc9}50 Seek {6189a1005e4f6dc613b8beb03d694ce50f0902974162d6a7dea944a970422cc9}50 de Key Lookup yapmakta. Index Seek işleminin üzerine gelip Tool Tip e baktığımız da en altta Seek Predicates de işlem detayını görmekteyiz.

Sağ tıklayıp proparties dediğimizde de aşağıda ki gibi Proparties sekmesinde detayları adım aıdm görmekteyiz.

Yukarıda ki örneğimizde Name kolonunu ‘=’ ile filtreledik. Peki LIKe ile aynı işlemi sorgularsak yani Name kolonunda aramayı ilk harfinden sonra ‘lade’ yazan ürün isimlerini aramak istediğimiz deki query nin Execution planı nasıl olur ?

-- Adının ikinci harfinden sonrası 'lade' olan ürünleri listeleyelim
SELECT Name, ProductNumber 
FROM Production.Product
WHERE Name like '_lade'

bu query mizinde execution planı yukarıda ki gibidir. Şimdi ise iki query mizi de aynı sonucu veriyor ve iki query mizi exec edip cost larına bakalım ;

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
-- Adı 'blade' olan ürünleri listeleyelim...
SELECT Name, ProductNumber 
FROM Production.Product
WHERE Name = 'blade'

-- Adının ikinci harfinden sonrası 'lade' olan ürünleri listeleyelim
SELECT Name, ProductNumber 
FROM Production.Product
WHERE Name like '_lade'

 

 

Gördüğünüz üzere ‘=’ operatörü ile olan I. query Cost umuz {6189a1005e4f6dc613b8beb03d694ce50f0902974162d6a7dea944a970422cc9}39 iken , LIKE operatörü ile olan II.Query mizin Cost u {6189a1005e4f6dc613b8beb03d694ce50f0902974162d6a7dea944a970422cc9}61 dir.

Bu tarz işlemlerimizde = operatörünü kullanmanızı hatta bu tarz filtrelemelrde hep = operatörü kullanmına zorlamaya çalışın işlemlerinizi.

WHERE bloğunda Function kullanımından kaçınınız.Bu sizin performansınızı kötü yönde etkiler ve çoğu durumlarda var olan Index i de kullanmaz. Hemen buna örnekleyelim ;

iki adet query miz var ve ikisi de aynı sonucu döndürmektedir. Biri Where boluğunda function kullanarak yazdığımız diğeri ise kullanmadan yazdığımız query.

Query I :

DECLARE @start DATETIME = '08/01/2014'
	   ,@end DATETIME = '08/31/2014'
SELECT
	SalesOrderID
   ,OrderDate
FROM Sales.SalesOrderHeader
WHERE OrderDate BETWEEN @start AND @end
GO

Query II :

SELECT
	SalesOrderID
   ,OrderDate
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = 2014
AND MONTH(OrderDate) = 8
GO

Tarih aralıkları ikisininde aynı aynı result dönmekte ama ikinci query miz de Where bloğunda function kullanılmış filtreleme alanında ve execution planına bakıldığında Index Scan yapmaktadır.

DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;
GO
DECLARE @start DATETIME = '08/01/2014'
	   ,@end DATETIME = '08/31/2014'
SELECT
	SalesOrderID
   ,OrderDate
FROM Sales.SalesOrderHeader
WHERE OrderDate BETWEEN @start AND @end
GO
DBCC DROPCLEANBUFFERS;
DBCC FREEPROCCACHE;
GO
SELECT
	SalesOrderID
   ,OrderDate
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = 2014
AND MONTH(OrderDate) = 8
GO

İki querynin Cost larını karşılaştırdığınızda bariz performans farkını görmektesiniz. Dediğimiz gibi ikinci query indexi kullanmadan direk Scan işlemi yaptı. Bu tarz işlemlerden kaçınmalıyız ve bu yüzden Where bloğumuzda mümkün olmadıkça function kullanmamalıyız.

 

Yukarıda Where bloğunda Function kullanmamanıza dikkat edilmesi gerektiğini örneklerle açıkladık. Şimdi ise şöyle bir konu daha var. Eğer siz ben mecburen Where de function kullanmam gerekiyor diyor iseniz o zamanda filtrelediğiniz kolonun üzerinde değil de filtrelemek için gönderdiğiniz değer üzerinde uygulamanızı tavsiye ederim.

Bu konuyu örnekle ele alalım , iki query miz var ve birinci query de productNumber kolonu üzerinde filtreleme yapılacak ama function ı kolon üzerinde kullanıp = opertörü ile ürünü arıyoruz. İkinci query miz de yine aynı şekilde ProductNumber kolonu üzerinden filtreleme yapılacak ama function ı kolona değil gelen değere uyguluyoruz ve iki query de aynı sonucu bize veriyor. Şimdi bu iki query nin davranışını inceleyelim;

Query 1 : 

SELECT Name, ProductNumber
FROM Production.Product
WHERE REPLACE(ProductNumber, '-', '') = 'BL2036'

Query I de Index Scan operasyonunu gerçekleştirdi.

Query 2 :

SELECT Name, ProductNumber
FROM Production.Product
WHERE ProductNumber = STUFF('BL2036', 3, 0, '-')

Query II de ise {6189a1005e4f6dc613b8beb03d694ce50f0902974162d6a7dea944a970422cc9}50 oranında Index Seek işlemi uygularken {6189a1005e4f6dc613b8beb03d694ce50f0902974162d6a7dea944a970422cc9}50 oranında da Clustered Index e Key Lookup operasyonu gerçekleştirdi.

Az önce de bahsettiğimiz üzere bu iki query de ki en büyük fark evet = operatörü kullandı her ikisi de ve en çok istediğimiz durum ama birinci query kolon üzerinde function işlemi uygularken ikinci query gelen değer üzerinde uyguladığı için daha perfromanslı ve tablo üzerinde ki Index i kullanmakta.

Bu iki query nin Cost larını karşılatırırsak ;

Execution planda resim net olarak gözükmekte. Query 1 in Cost u {6189a1005e4f6dc613b8beb03d694ce50f0902974162d6a7dea944a970422cc9}66 iken Query 2 nin Cost u 34 dür.

NOT : Bu makalede her konu çok önemli ve uygulanması gereken ve sizlerin query leriniz de ve sistemleriniz de performansı arttırıcı yöntemlere hakim olarak yapınızın efor maliyetini düşürmenizi sağlamaktadır.

Kolay Gelsin…

4 Replies to “SQL Server SARGability Session I”

    1. Selam Dilara ,
      Ever SARGability series makalelerim çok değerli ve okumanızı ve sistemlerinizde ve query lerinizde bu anlattıklarımı uygulamaya çalışmanızı istiyorum. Yararını hem sizlere anlattığım demo larda hemde kendi sistemlerinizde denediğinizde daha net anlayacaksınız. Diğer serileri de hazırlanıyor makalenin. Bu makaleye eş değer ve farklı bilgiler de alabileceğin SQL Türkiye Platformunda bir çok makale var. Serinin ikinci makalesi gelmeden onları inceleyip Demolarını gerçekleştirirsen senin faydana olacaktır.
      Teşekkürler.

  1. Hocam ,
    Bunların dışında ki konularda ki performans konularını ne zman ele alacaksınız. Dört gözle o konuları bekelmekteyiz.

    1. Selam Sabri ,

      Aslında ara ara bu sayfayı güncelliyorum ve bunların dışında da platform(www.sqlturkiye.com) üzerinde de performans ile ayrı ayrı yazdığım makaleler mevcut. SQLTurkiye.Com Platformunu iyi incelersen bu makaleleri bulabilirsin.

      Aşağıda da bir kaç bu tarz örnek makale linklerini paylaşıyor olacağım.

      Performans çok geniş ve derin bir konu. Konuyu hangi aşamada ele aldığın ve nasıl yorumladığın, yorumlama durumun ve doğrulu sıkıntın hızlı çözülmesine destek olacak noktalar. Platformu güncel bir şekilde takip etmende fayda var.

      https://sqlturkiye.com/sql-server-query-performans-ipuclari/

      https://sqlturkiye.com/sql-server-onemli-execution-plan-operatorleri-2-egitimi/

      https://sqlturkiye.com/2866-2/

      https://sqlturkiye.com/in-operatoru-ile-ilgili-problemler/

      https://sqlturkiye.com/sql-server-plan-guide-egitimi/

      vb.

      Kolay Gelsin.

Leave a Reply

Your email address will not be published. Required fields are marked *