Pazartesi , 20 Kasım 2017

Indeksleri Unique Olusturmanin Performansa Etkisi

Unique indeksler, oluşturuldukları kolondaki değerlerin tekrar etmeyeceğini garanti eden indekslerdir. Daha açık bir ifadeyle tablomuzda bir kolonu kullanarak bir Unique indeks oluşturduğumuzda ilgili kolona aynı değerden sadece bir tane girilebileceği garanti edilmiş olur. Bu sebeple Unique indekslerin en sık kullanıldığı noktalardan biri de tekrar etmemesi gereken veriler için bütünlüğü sağlamaktır. Örneğin üye bilgilerinin tutulduğu tabloda TC kimlik numarası veya email adresi gibi bilgilerin tekrar etmemesi gerekiyor. Bu sebeple bu alanlar üzerinde veri bütünlüğünü sağlamak amacıyla da Unique indeks oluşturulabilir.

Unique indeksler her ne kadar veri bütünlüğü sağlamak için kullanılsa bile tablolar üzerinde oluşturduğumuz indeksleri Unique olarak işaretlemek bize performans kazandıracaktır. Çünkü Query Optimizer bu indeksi kullanan ya da kullanacak olan sorgular için dönecek olan değerin bir olacağını bilecek ve ona göre davranacaktır.

Unique indekslerin performans etkisini örnek üzerinde görmek için ilk olarak aşağıdaki gibi tablolarımızı oluşturalım. Her iki tablomuzda aynı yapıda olup öncelikle her iki tabloya da aynı yapıda ve sayıda veri ekleyip daha sonra ilk tablomuz üzerinde Unique olmayan bir indeks, ikinci tablomuzun üzerinde ise Unique bir indeks tanımlayarak sorgu performansını karşılaştıralım. Tablolarımızı aşağıdaki gibi oluşturabiliriz.


CREATE TABLE Data(

Id INT identity
,NAME VARCHAR(100)
)

GO

CREATE TABLE UniqueIndexData(

Id INT identity

,NAME VARCHAR(100)
)

GO

Yukarıdaki gibi tablolarımızı oluşturulduktan sonra aşağıdaki gibi her iki tablomuzdaki değerler aynı olacak şekilde 100 tane kayıt ekleyelim.


WHILE ((SELECT count(1) FROM UniqueIndexData) < 100)

BEGIN

DECLARE @data VARCHAR(100) = newId()

INSERT INTO Data VALUES (@data)

INSERT INTO UniqueIndexData VALUES (@data)

END

GO

Yukarıdaki gibi her iki tablomuza da 100 tane kayıt ekledik. Şimdi aşağıdaki gibi tablolarımızı sorgulayıp kontrol edebiliriz.


SELECT * FROM Data

SELECT * FROM UniqueIndexData

Unique_Index1

Yukarıdaki resimde gördüğümüz iki tablomuzda aynı verileri içermektedir. Artık tablolarımız üzerinde indekslerimizi oluşturabiliriz. Her ikisi de aynı veriyi içeren tablolarımızdan ilki üzerinde Unique olmayan bir indeks tanımlarken diğer tablomuz üzerinde aynı kolon üzerinde Unique indeks tanımlayalım.


CREATE INDEX Ix_Name2_NonUnique ON Data(Name)

CREATE UNIQUE INDEX Ix_Name_Unique ON UniqueIndexData(Name)

Yukarıdaki gibi indekslerimizi de oluşturduktan sonra şimdi her iki tabloda da Name kolonu üzerinden sorgulama yapalım ve her iki sorgumuzun da Execution Planlarını inceleyelim.


SELECT *

FROM UniqueIndexData

WHERE NAME = '662DAEBB-496B-4D51-8172-E11B6B051F34' 

Yukarıdaki sorgumuzun Execution planını incelediğimizde aşağıdaki gibi bir plan oluşturulduğunu görebiliriz.

Unique_Index2

Yukarıdaki resimde gördüğümüz üzere Unique indeks oluşturduğumuz tabloda ilgili kolon kullanılarak yapılan sorgulama işleminde Query Optimizer bu indeksin kullanılmasına karar vermiştir.   Şimdi benzer sorguyu diğer tablomuz için kullanalım. Sorgumuz ve Execution planımız aşağıdaki gibi olacaktır.


SELECT *

FROM Data

WHERE NAME = '662DAEBB-496B-4D51-8172-E11B6B051F34' 

Unique_Index3

Yukarıdaki resimden de göreceğimiz üzere tablomuzda Name kolonu üzerinde Unique olmayan bir indeks oluşturmuş olmamıza rağmen Query Optimizer indeksi kullanmak yerine Table Scan işlemini tercih etmiştir. Bu tercihin en önemli sebebi ise her iki sorgumuzda da kullanılan ya da kullanılabilecek indeksler nonclustered indeks olması ve sadece Name kolonunu içerdiği için Id kolonuna erişmek için Lookup işlemi yapmak zorunda kalacaktır. İlk sorgumuzda Unique indeks olması sebebiyle Query Optimizer Lookup işleminin(RID Lookup) bir defa yapılacağından eminken ikinci sorgumuzda Lookup işleminin bir defa yapılacağından emin değildir. Bu sebeple ikinci sorgumuzda fazla Lookup işlemi yapmak yerine Query Optimizer Table Scan işlemini seçmiştir.

 

Hakkında ismailadar

Bir yorum

  1. Teşekkürler İsmail hocam, faydalı bir performans makalesi olmuş.

Cevapla

E-posta adresiniz yayınlanmayacak. Required fields are marked *

*


*

Şu HTML etiketlerini ve özelliklerini kullanabilirsiniz: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>