MSSQL Server Filtered Index

Bu makalede Mssql Server Filtered Index konusunu ele almış olacağız. Filtered Index, SQL Server 2008 ile gelen, optimize edilmiş bir nonclustered index’tir.  MS SQL Server’da Filtrelenmiş İndeks (Filtered Index), bir tablodaki belirli bir veri alt kümesi üzerinde oluşturulan bir indeks türüdür. Filtrelenmiş indeksler, sorgu performansını artırmak ve depolama alanını optimize etmek için kullanılır. Bu indeksler, belirli bir WHERE koşuluna dayalı olarak sadece belirli satırları içerir. Oluşturulan filtrelenmiş indexs’ler filtrelenmiş istatistiklere sahiptir.

Filtrelenmiş indeksler, sorguların yalnızca belirli bir veri alt kümesi üzerinde çalışmasını sağlar. Bu, sorgu performansını önemli ölçüde artırabilir. Sadece belirli bir koşulu sağlayan veriler indekslendiği için, standart bir indeksle karşılaştırıldığında daha az disk alanı kullanılır. Daha az veri indekslendiği için, indekslerin yeniden oluşturulması veya güncellenmesi daha hızlıdır. Büyük tabloların sadece sık kullanılan alt kümeleri için indeks oluşturularak kaynak tüketimi azaltılabilir. Çok fazla filtrelenmiş indeks, güncelleme ve ekleme işlemleri sırasında bakım yükünü artırabilir. Ayrıca verinin tamamını içermediği için diskte daha az yer kaplarlar.

Filtrelenmiş İndeks genellikle Bir sütundaki NULL olmayan değerleri indekslemek istediğinizde veya belirli bir sabit değere sahip olan satırlar üzerinde indeks oluşturmak için (örneğin, ‘Durum’ = ‘Aktif’) kullanılabilir. Sık kullanılan veya sorgularda hedeflenen belirli bir veri kümesi için filtreleme yapılabilir. Herhangi bir zaman aralığında  son 30 güne ait veriler için sorgulama yapmak istendiğinde.

Örneklerimize geçmeden önce filtrelenmiş index sadece Non-clustered Index yapılarımızda görülmektedir.

Filtrelenmiş İndeks Nasıl Oluşturulur?
Filtrelenmiş indeks oluşturmak için CREATE INDEX komutunu kullanırız ve WHERE koşulu ekleriz.

1-Index tanımlarken belirtilen sütündaki null değerleri almak istemediğimiz zaman oluşturulabileceğini söylemiştik. Aşağıdaki sorgu buna bir örnek gösterilebilir.

CREATE NONCLUSTERED INDEX IX_Person_Name
ON Person ([Name])
WHERE [Name] IS NOT NULL WITH ( ONLINE = On, MAXDOP = 16, FILLFACTOR = 90) 

Yukarıdaki  komut ile  yalnızca [Name] sütunu NULL olmayan satırlar için bir indeks oluşturur.

2-Belirli olan sabit değerler için index oluşturulabilir.

CREATE NONCLUSTERED INDEX IX_Person_Stok
ON Person (Stok)
WHERE Stok>20 WITH ( ONLINE = On, MAXDOP = 16, FILLFACTOR = 90) 

Yukarıdaki  komut ile  yalnızca stok sütunu 20 değerinden büyük olan  satırlar için bir indeks oluşturur.
Not: Where koşulunda indexs kolonundan farklı bir kolonda olabilir.

3- Index kolonunda belirtilen Tarih aralığı üzerinde indeks oluşturulabilir.

CREATE NONCLUSTERED INDEX IX_Siparisler_Tarih
ON Siparisler (Tarih)
WHERE Tarih >= '2025-01-01' WITH ( ONLINE = On, MAXDOP = 16, FILLFACTOR = 90) 

Yukarıdaki komut belirtilen tarih ve sonrasındaki değerler için bir index yapımızı oluşturmaktadır.

Aşağıdaki komut ile bir tablo altında filtrelenmiş index olup olmadığını  İndex üzerindeki row count sayısını görebiliriz.

SELECT i.index_id, i.name, i.type_desc, ps.reserved_page_count, ps.used_page_count,
ps.reserved_page_count*8 as Size_KB,
ps.row_count, i.filter_definition
FROM sys.dm_db_partition_stats ps
INNER JOIN sys.indexes i ON ps.object_id = i.object_id AND ps.index_id = i.index_id
WHERE ps.object_id = OBJECT_ID('Person.Address')

İlgili kolona filtrelenmemiş index oluşturduktan sonra row count değerinin 19614 değilde 362 olarak görülmektedir. Bu yapıda performans anlamında çok iyi bir durum olarak görülmektedir.

Oluşturduğumuz filtrelenmiş index ve filtrelenmemiş index ile select sorgusu çekelim.

SET STATISTICS IO ON

--Normal NonClustered Index'i force ederek

select * from Person.Address WITH (INDEX=IX_Address_AddressLine2_Filtresiz,NOLOCK)

where AddressLine2='Unit E'

--Filtered Index'i force ederek

select * from Person.Address WITH (INDEX=IX_Address_AddressLine2,NOLOCK)

where AddressLine2='Unit E'

Yukarıdaki index yapılarını karşılaştırdığımızda ne kadar IO yaptığını ve execution plan aralarındaki farkı  görebiliriz. İlgili kolunda kayıt sayısı az olduğu için hemen hemen aynı sonucu dönmüş oldu.

Ayrıca oluşturulan filtered index properties ekranına girdikten sonra  filtrelenmiş kolunu görebiliriz.

Sorgularımızda şart ifadesinden sonraki ifadeleri Yukarıdaki resimde bulunan filter bölümüne kopyalanıp yapıştırılırsa aynı yapıya gelmektedir. Komut ile yapmayıp bu şekilde yapılabilir.

Filtrelenmiş İndekslerin Kullanımında Dikkat Edilecekler
1. Filtrelenmiş indeks, özellikle çok büyük tablolarda belirli bir alt küme üzerinde çalışacak sorgular için etkili olur.
2. Filtre koşulu ve sorgu yapısının uyumlu olması gerekir. Aksi takdirde indeks kullanılmaz.
3. Filtrelenmiş indeksin sorgu planında kullanıldığından emin olmak için Query Execution Plan kontrol edilmelidir.

Performans Analizi
Filtrelenmiş indeksler, tablo boyutuna ve sorgu yapısına bağlı olarak sorgu sürelerini büyük ölçüde azaltabilir. Ancak gereksiz yere birçok filtrelenmiş indeks oluşturmak, indeks yönetimini zorlaştırabilir.

Bu makalede Mssql Server yapısında Filtered Index yapısını görmüş olduk. Başka bir makalede görüşmek dileğiyle..

“İnkar edenleri ise, dünyada ve ahirette şiddetli bir azapla azaplandıracağım. Onların hiç yardımcıları yoktur.” Al-i İmran Suresi, 56. Ayet


Author: Yunus YÜCEL

Bir yanıt yazın

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