Yazd脹脹m脹z bir sorgu 巽al脹t脹r脹lmadan 旦nce, SQL Server taraf脹nda sorgumuzda istediimiz veriye en h脹zl脹 nas脹l eriebileceimiz sorusuna cevap veren ve bizim veriye eriim s脹ram脹z脹 tayin eden Query Optimizer bileenidir.
Daha a巽脹k bir ifadeyle , karma脹k yani birden fazla tablo veya ifade i巽eren sorgular脹m脹zda 旦ncelikle hangi tabloda ki veriye erierek sorgu sonucuna daha h脹zl脹 eriebilirim ? Hangi tablo 端zerinde ki hangi indeksi kullanarak istenen veriye daha h脹zl脹 eriebilirim. Hatta baz脹 durumlarda biz belirtsek dahi iki tabloyu ne ekilde JOIN edersem yani birletirirsem daha h脹zl脹 veriye eriebilirim gibi sorular脹 bizim yerimize soran ve sorgumuzun en optimum ekilde 巽al脹mas脹 i巽in bir 巽al脹ma plan脹 (Execution Plan) oluturan SQL Server bileenidir.
Execution Plan : Query Optimizer taraf脹ndan hesaplanan ve bir sorgunun en ideal ekilde 巽al脹mas脹 i巽in bize 旦nerilen optimum yoldur.
Table Scan : zerinde Clustered Index bulunmayan tablolarda veriye erimek i巽in t端m tabloyu tarama ilemine denir. zerinde Clustered Index tan脹mlanmama脹 tablolara HEAP table denmektedir. K脹saca bir tabloda ki t端m kay脹tlar脹n teker teker okunama ilemine denmektedir.
Clustered Index Scan : Bu ilem de Table Scan ilemi gibi SQL Server Clustered Index 端zerinden tablodaki kay脹tlara sat脹r sat脹r eriip ilem yapt脹脹n脹 g旦sterir. Asl脹nda bak脹ld脹脹nda Index in kullan脹lmad脹脹n脹 g旦rmketesiniz. 端nk端 tablodaki t端m veri,ye Table Scan de ki gibi sat脹r sat脹r eriip sonra sonucu d旦nd端recektir.
SQL Server脹n bu s箕ekilde is箕lem yapmas脹n脹n sebebi sorgu sonucunda c箕ok fazla kay脹t dondurulecegi ic箕in tablodaki verilere Table Scan is箕lemindeki gibi sat脹r sat脹r eris箕menin daha h脹zl脹 olacag脹na karar vermesinden kaynaklanmas脹d脹r. Bu sebeple Clustered Index Scan is箕lemi ic箕in Table Scan is箕lemi ile hemen hemen ayn脹d脹r demek de yanl脹s箕 bir tabir olmaz. C箕unku SQL Server clustered indeksi filtreleme amac箕l脹 kullanmadan tum veriye sat脹r sat脹r eris箕mis箕tir.
Bu yuzden ozellikle buyuk tablolardaki veriye eris箕en sorgular脹m脹z脹n Execution planlar脹nda Clustered Index Scan operatorunu gorunce ne yapmal脹y脹z sorusu akla gelebilir. Cevap asl脹nda c箕ok zor degil. Sorgumuz sonucunda kullanabilecegimiz bir Clustered indeksimiz zaten var bu yuzden sorgumuzdan donen kay脹t say脹s脹n脹 eger gerekli degilse azaltabiliriz. Bunun ic箕in ozellikle WHERE operatoru ile belirtmis箕 oldugumuz kos箕ullar脹 tekrar gozden gec箕irip eger gerekli degilse sorgu sonucunda donen kay脹t say脹s脹n脹 azaltabilirsek istedigimiz sonuca ulas箕abiliriz.
K脹saca Index lerin al脹ma Prensibi Deinelim ,
Index
Clustered Index Seek : Index Scan ile Index Seek ilemleri tamamen birbirinden farkl脹d脹r. Bunun en b端y端k sebebi Scan ileminde tabloda ki t端m verileri sat脹r sat脹r tarayarak sonuca gidilirken. Seek ilemlerinde direkt datan脹n kendisine eriim salanm脹 oluyor.
Bu sebeplerden dolay脹 Seek ilemi Scan ilemlerdinden daha performansl脹d脹r. ( ou durumlarda !)
NonClustered 脹ndex Seek : Nonclustered Index ilemide direkt dataya eriimimizi Nonclustered Index 端zeirnden erime ilemine denmektedir.
Index kullan脹m amac脹m脹z , istenilen bilgiye daha az veri okuyarak daha h脹zl脹 bir ekilde erimektir.
K脹saca Index lerin al脹ma Prensibi Deinelim ,
SQL Serverda klasik Index yap脹s脹na deinecek olur isek ,
Index ler B-Tree (Balanced Tree) yap脹s脹na organize olmu durumdad脹rlar. B-Tree nin en 端st page inden (Root Level) balayarak aa巽 端zerinde kay脹d脹 bulmak i巽in dallanmalar yap脹l脹r.Root Level dan sonra Intermediate Level Page ler gelmektedir.Bu page ler tabloda ki kay脹t say脹s脹na ve index in boyutu gibi durumlara g旦re 1 leveldan fazla olabilmektedir. Yani bir B-Tree yap脹s脹nda 1 level Root, 1 lefel Leaf ve 1 ya da daha fazla Intermediate Level bulunmaktad脹r.
Root ve Intermediate Level lara Non-Leaf Level denmektedir.
Hem Clustered hem de NonClustered Index ler i巽in Non-Leaf Level Page lerde Index Key ler bulunmaktad脹r. rnein, Personel_ID kolonu i巽in Clustered Index tan脹mland脹ysa Non-Leaf Level Page lerde bu Personel_ID kolonu bulunur. Personel_ID Clustered Index in Key kolonudur. Eer bu Clustered Index unique olarak tan脹mlanmam脹sa SQL Server arka tarafta bu veriyi Unique letirmek i巽in her bir veri i巽in 4 byte l脹k Integer bir kolon tutmaktad脹r. Bunada Uniquifier konu denmektedir.
Non-Leaf Level Page lerde ayr脹ca NonClustered Index le ri巽in , Eer NonClustered 脹ndex ler Unique deil ise , Heap 脹n POINTER bilgileri ya da Clustered Index in KEY kolon bilgileri bulunur.
NOT : SQL Server i巽in bir 脹ndex in Unique olup olmamas脹 oluturulurken kullan脹lan Unique s旦zc端端ne bal脹d脹r. Yani Index I olutururken UNIQUE ifadesi kullan脹lmazsa Index unique deildir.
imdi gelelim B-Tree nin enlat Level I olan Leaf Level Page lere. Bu page lerde bulunan bilgiler Clustered ya da NonClustered 脹ndex lere g旦re farkl脹l脹k g旦stermektedir.
Clustered Index i巽in , Leaf Level da verinin t端m kolonlar脹 ile beraber kendisi bulunmaktad脹r. B-Tre nin Leaf Level 脹nda Index I bulduumuz anda verinin kendisine de erimi oluruz.
NonClustered Index i巽in , Leaf Levelda ise Include edilmi kolonlar ve ayr脹ca verinin geri kalan脹na eriebilmek i巽in Row Locator yani sat脹r belirleyici bilgileri bulunur.
NEML聴 NOT : NonClustered Index te aranan kay脹t bulunduktan sonra Cluster ya da Heap a y旦nelerek kay脹d脹n geri kalan脹n脹 bulma ilemine LookUp denilmektedir.
RNEK DEMO : INDEX-PAGEveLookUp-Ornek.sql dosyas脹 i巽erisinde.
RNEK Anlat脹m脹 :
rneimize balamadan iki adet Clone tablo oluturuyoruz . Address tablosunun bir Clone unda Clustered ve NonClustered Index ekliyoruz ki bu tablomuz AddressDemo_Clustered tablosu. Dier Clone tablomuz ise Clustered Index olmadan NonClustered 脹ndex oluturuyoruz. Bu tablomuzda AddressDemo_Heap tablomuzdur.
AddressDemo_Clustered tablomuza AddressID kolonuna sqltr_CIX_AddresDemo_AddressId isimli bir Clustered Index oluturuyoruz.
City alan脹na da sqltr_NCIX_AddressDemo_Clustered_City isimli bir NonClustered Index oluturuyoruz.
Daha sonra 'AddressDemo_Clustered tablosunun Page lerini listelemek i巽in Undocumented DBCC IND komutu ile Tablo Page lerini listeliyoruz.
DBCC IND ( 'AdventureWorks2016', 'AddressDemo_Clustered', 2)
GO
Syntax :
dbcc ind( dbid|dbname, objid|objname, printopt = {-2|-1|0|1|2|3} )
1 data page
2 index page
3 veya 4 text pages
8 GAM page
9 SGAM page
10 IAM page
11 PFS page
DBCC IND komutundan PageId yi al脹yoruz ve Page yap脹s脹n脹 inceliyoruz DBCC PAGE komutu ile
DBCC traceon(3604)
DBCC page('AdventureWorks2016', 1, 59536, 3)
GO
DBCC PAGE ({dbid|dbname}, pagenum [,print option] [,cache] [,logical])
G旦rd端端b端z 端zere Page i巽erisinde City kolonu NonClustered Index in Key kolonu, AddressId ve Uniqufier kolonlar脹 ise verinin geri kalanlar脹na Lookup yapabilmek i巽in tutulan bilgilerdir.
Heap tablomuzda yani Clustered Index olmayan ama NonClustered index olan 旦rneimizi incelediimizde ise g旦rd端端n端z 端zere Lookup yapmak i巽in gerekli Clustred Key ve Uniqufier kolonlar脹 yerine RowID Key kolonu (HEAP RID (Key)) bulunmaktad脹r.
B-Tree 端zerinde arama ilemi en 端st leveldan (Root) yap脹lmaya balan脹r. Aa巽 mant脹脹nda dier kollara dallan脹larak Intermediate levellarda arama devam ettirilir. Araman脹n sonunda aranan keye Leaf Levelda eriilir. Eer bu bir Clustered Index ise veriye direk eriilmi olur, NonClustered Index ise ve key kolonlar hari巽 baka kolonlara da ihtiyac脹m脹z var ise heape ya da Clustered Indexe LookUp yap脹larak dier ihtiya巽 olunan bilgiler getirilir
ZET OLARAK :
Eer table clustered index i巽eriyorsa; row locator Clustered Index keylerini i巽erir. Eer Clustered Index unique olarak tan脹mlanmad脹ysa, row locator bu keyleri unique hale getirmek i巽in keyin sonuna 4 bytlel脹k bir belirleyici (uniqueifier) koyar. NonClustered Indexin Leaf Level脹ne eriildiinde ve Clustered Indexe Key LookUp yap脹lmas脹 gerektiinde Clustered key unique deil ise Clustered Indexte arama hem keyler hem de bu uniqueifier kolonu ile beraber yap脹l脹r.