INDEX SEEK , INDEX SCAN , TABLE SCAN

Ridvanozayas
Vakıf Katılım Ar-Ge Merkezi
4 min readJun 21, 2024

Uygulamalı olarak gitmek için öncelikle tablolarımızı oluşturup , tablolarımızı kendi oluşturacağımız verilerle ile dolduracağız.

CREATE TABLE dbo.SALES (

[ID] int IDENTITY(1,1) NOT NULL,

[DATA_DATE] date NULL,

[AMOUNT] decimal(18,2) NULL,

[TOTAL_AMOUNT] decimal(18,2) NULL,

[DESCRIPTION] varchar(100) NULL,

)

Tablomuz boş şekilde veritabanı üzerinde oluştu.

Sonrasında oluşturduğumuz tabloya döngü ile yine kendi oluşturduğumuz veriler ile insert edeceğiz.

DECLARE @sayac int = 1

DECLARE @sayac2 int = 500001

while @sayac < @sayac2

begin

INSERT INTO dbo.SALES (DATA_DATE, AMOUNT,TOTAL_AMOUNT,[DESCRIPTION])

VALUES ( ‘2005–07–17’, 2000.12 ,2000.12,’TEST_TEST_1')

INSERT INTO dbo.SALES (DATA_DATE, AMOUNT,TOTAL_AMOUNT,[DESCRIPTION])

VALUES ( ‘1900–01–01’, 45332 ,44,’TEST’)

INSERT INTO dbo.SALES (DATA_DATE,AMOUNT,TOTAL_AMOUNT,[DESCRIPTION])

VALUES ( ‘2024–01–01’, 231133 ,777,’’)

INSERT INTO dbo.SALES (DATA_DATE, AMOUNT,TOTAL_AMOUNT,[DESCRIPTION])

VALUES ( ‘2018–01–01’, 69549 ,22678905,’BİLİNMİYOR’)

INSERT INTO dbo.SALES (DATA_DATE, AMOUNT,TOTAL_AMOUNT,[DESCRIPTION])

VALUES ( ‘2009–11–01’, 8482820 ,63355,’’)

INSERT INTO dbo.SALES (DATA_DATE,AMOUNT,TOTAL_AMOUNT,[DESCRIPTION])

VALUES ( ‘2005–07–17’, 3849493 ,43224,’TEST_TEST’)

INSERT INTO dbo.SALES (DATA_DATE, AMOUNT,TOTAL_AMOUNT,[DESCRIPTION])

VALUES ( ‘2005–07–17’, 74748339,34433,’TEST_TEST’)

set @sayac = @sayac+1;

END;

GO

Döngüyü 50.000 defa döndürerek her seferinde 7 kayıt insert ediyoruz. Sorgu bitiminde tablomuzda 3.5 milyon kayıt var.

Şimdi aşağıdaki sorguyu çekiyoruz.

SELECT * FROM dbo.SALES WITH (NOLOCK)

WHERE [DATA_DATE]=’2005–07–17'

1.5 milyon kayıt geliyor . Hiç Index oluşturmadan Execition Plan’a bakıyoruz.

Hiç Index oluşturmadığımızda filitre kısmını aratırken Execition Plan’dan Table Scan yaptığını görüyoruz.

Şimdi ID alanından Clusterd Index oluşturalım.

CREATE CLUSTERED INDEX [ClusteredIndex_SALES_ID] ON [dbo].[SALES]

(

[ID] ASC

)

Cluster Index oluştu. Şimdi tekrar Execition Plan’a bakıyoruz.

Cluster Index oluşturduğumuzda Table Scan’den Index Scan dönüştü.

Filtre kıstındaki alan farklı alan olsana tablo üzerinde Clustered Index varsa Sql Table Scan yerine Index Scan yapar. Table Scan aramayı tüm tablo satırları üzerinden yaparken Index Scan aramayı Index üzerinden yapıyor yani tablo satırları Index aracılığı ile alınır.

Index Scan, Table Scan göre daha az maliyetlidir Index Scan I/O okuma sayısını önemli ölçüde azaltır ve genellikle Table Scan’den daha iyi performans gösterir.

Şimdi Execution Planın önerdiği Index’i oluşturalım.

Aşağıdaki gibi önerdiği Index sekmesine sağ tıklayarak Missing Index Detaile tıklıyoruz.

CREATE NONCLUSTERED INDEX [IX_SALES_DATA_DATE]

ON [dbo].[SALES] ([DATA_DATE])

INCLUDE ([AMOUNT],[TOTAL_AMOUNT],[DESCRIPTION])

Bu Index’i oluşturduktan sonra Execition Plan’a tekrar bakıyoruz.

Index Seek yaptığını görüyoruz.

Index Seek yalnızca uygun satırlara ve bu uygun satırları içeren sayfalara dokunur. Maliyet, tablodaki toplam satır sayısı yerine nitelendirilen satırların ve sayfaların sayısıyla orantılıdır.

Sql Table Scan yaptığında tablodaki her satırı tek tek inceler ve filtre koşulu ile eşleşiyorsa sonuç kümesine dahil eder. Küçük tablolarda veriler tek seferde yüklenir ve çok sorgu süresinde çok fark görünmez fakat büyük tablolarda bu ciddi zaman ve performans kaybına sebep olur.

Fakat her durumda Index konulmamalıdır , Index’de maliyeti olup insert komutlarında hem tabloda hem Index’e yazdığından daha fazla alan kaplama maliyetine ve yavaşlığa sebep olur. Ayrıca Index’in bakım maliyetleri vardır. Fayda maliyet analizi yapılarak gerçekten ihtiyaç varsa Index konulmalıdır.

Örneğin 3.5 milyonluk küçük boyutlu bir tabloda Table Ccan ile Index Seek yapmasında zaman farkı anlaşılmazken tablolar büyüdükçe Index önem kazanır ve çalışma süresi gözle görülür şekilde fark eder.

Gereksiz yere Index kullanımı yukarda belirtiğim sebeplerle fayda yerine zarar sağlar.

TABLE SCAN

Sql Table Scan yaptığında tablodaki her satırı tek tek inceler ve filtre koşulu ile eşleşiyorsa sonuç kümesine dahil eder. Küçük tablolarda veriler tek seferde yüklenir ve çok sorgu süresinde çok fark görünmez fakat büyük tablolarda bu ciddi zaman ve performans kaybına sebep olur.

INDEX SCAN

Tablo üzerinde Clustered Index varsa Sql Table Scan yerine Index Scan yapar. Table Scan aramayı tüm tablo satırları üzerinden yaparken Index Scan aramayı Index üzerinden yapar yani tablo satırları Index aracılığı ile alınır.

Index Scan, Table Scan’e göre daha az maliyetlidir Index Scan I/O okuma sayısını önemli ölçüde azaltır ve genellikle Table Scan den daha iyi performans gösterir.

INDEX SEEK

Index Scan nitelikli olsun ya da olmasın tablodaki her satıra dokunur, maliyet tablodaki toplam satır sayısı ile orantılıdır.

Index Seek yalnızca uygun satırlara ve bu uygun satırları içeren sayfalara dokunur. Maliyet, tablodaki toplam satır sayısı yerine nitelendirilen satırların ve sayfaların sayısıyla orantılıdır.

Performans sıralamasını aşağıdaki gibi yapabiliriz.

INDEX SEEK > INDEX SCAN > TABLE SCAN

--

--