Non-clustered index
Datanın tutuluş şeklini gösteren query;
CREATE INDEX IX_LastAccessDate_Id_Age ON dbo.Users (LastAccessDate,Id,Age) SELECT LastAccessDate,Id,Age FROM dbo.Users ORDER BY LastAccessDate,Id,Age
Missing Index Önerisi
Genelde sadece WHERE clause’a odaklanır, çünkü bu işlemi micro saniyeler içinde gerçekleştirip query’nin süresine etki etmemesi gerekiyor.
WHERE Clause – Index for Equality Queries
Aşağıdaki sorgu için index en iyi index nedir?
SELECT DisplayName,Id,Age FROM dbo.Users WHERE DisplayName=‘John' /* Missing Index */ CREATE INDEX IX_DisplayName ON dbo.Users (DisplayName) /* Correct Index */ CREATE INDEX IX_DisplayName_includes ON dbo.Users (DisplayName) INCLUDE (Age)
Not : Id kolonu Clustered Index olduğu için Non-Clustered Index’e otomatik olarak include olarak dahil olur.
SELECT DisplayName,Id,Age FROM dbo.Users WHERE DisplayName=‘John’ AND Age = 32 /* Correct Indexes */ CREATE INDEX IX_DisplayName_Age ON dbo.Users (DisplayName,Age) /* Read 5 Pages */ CREATE INDEX IX_Age_DisplayName ON dbo.Users (Age,DisplayName) /* Read 6 Pages */ CREATE INDEX IX_DisplayName_includes ON dbo.Users (DisplayName) INCLUDE (Age) /* Read 16 Pages */
Bu durumda hangi index’in kalacağı kararı sizin. Genelde ilk iki index’te page sayısı olarak bile bir fark olmayacaktır.
Not : 3. Index ilk sorgunun da yoğun kullanıldığı durumlarda, yer açısından kazanç sağlamak için mantıklı bir seçim olabilir.
WHERE Clause – Index for Equality and InEquality Queries
SELECT DisplayName,Id,Age FROM dbo.Users WHERE DisplayName=‘John’ AND Age != 32 /* Correct Indexes */ CREATE INDEX IX_DisplayName_Age ON dbo.Users (DisplayName,Age) /* Read 13 Pages -Index Seek */ CREATE INDEX IX_Age_DisplayName ON dbo.Users (Age,DisplayName) /* Read 4667 Pages -Index Seek */ /* Hidden Scan */ CREATE INDEX IX_DisplayName_includes ON dbo.Users (DisplayName) INCLUDE (Age) /* Read 16 Pages */
Selectivity
Query’lerde sık kullanılan ve büyük filtrelemeler yapacak koşullar selectivity’dir. Kolonların içindeki unique değerler selectivity değildir.
Örneğin; Users tablosundaki LastAccessDate neredeyse tüm tabloda unique değerler barındırmaktadır. Ancak sorgularda LastAccessDate =‘2020-01-01 01:30:59’ şeklinde değil LastAccessDate < GETDATE() olarak kullanıldığı için unique olması işimize yaramamaktadır.
Daha çok equality koşulların unique ve sorgulama sıklığına bakılarak selectivity yüksek denilebilir.
# Bölüm sonu canavarı
- Query’lerdeki koşullar equality ise index key kolon sıralamasının pek önemi yoktur.
- Query’lerdeki koşullar inequality ise index key kolon sıralaması ÇOK önemlidir. Index’teki ilk kolon istenen datayı getirebilmek için okunacak row sayısını azaltmakta yardımcı olacaktır.
- Seek operatörü her zaman gerçekten seek değildir. Bu tarz seek işlemlerine hidden scan olarak adlandırırız. *Bkz : Son örnek
- Selective kolonları ilk sıraya koymak arama esnasında okunacak datayı azaltacaktır.