1. INDEX YÖNETİMİ:
lndex; bir veri tabanı içinde bulunan verileri hızlı açmak daha doğrusu hızlı
sorgulamak için çok gerekli olan bir yapıdır. Ancak zamanla index yapısı bozulabilir ve
bunun yeniden yapılandırılması gerekir. İşte bu yüzden veri tabanı yöneticisinin; index
oluşturma(Create lndex), değiştirme(Alter Index) ve silme(Drop lndex) işlemlerini
çok iyi bilmesi gerekmektedir.
SQL Server 2012 içinde bir veri sayfası (Data Page) içindeki bir satır(Row)
lokasyonuna index uygulanabilir. Bu da bir tablodaki tüm veri sayfalarına uygulanan
yönteme göre avantajlar sağlar.
Index yapısı, veri tabanının performansını arttırmak için kullanılır. Bu kısımda
temel index yapısını nerede ve nasıl kullanacağımızı inceleyeceğiz.
SQL SERVER. VERİLERİ NASIL DEPOLAR ve ACAR?
SQL Server'ın verileri nasıl açtığını anlamak için, ilk önce verileri nasıl depoladığını
bilmek gerekir.
Veri Nasıl Depolanır?
*** Tablo içindeki sürekli satırlardan oluşan veri sayfalarının toplamına hesap adı
verilir.
*** Her veri sayfası(data page) 8 KB' lık bilgilerden oluşur. Bu sayfalardan sekiz
tanesinin biraraya gelerek oluşturduğu gruba extent adı verilir.
2. *** Veri satırları(data rows) belirli bir sıra dahilinde tutulmaz ve veri sayfalarında
belirli bir sıra yoktur.
*** Veri sayfaları bağlı bir liste içine; bağlı değildir.
*** Bir sayfa içine bir satır eklendiği zaman, eğer sayfa dolu ise veri sayfaları bölünür
ve yeni bir sayfaya yazılmaya başlar.
Veri Sayfaları(Data Pages)
Sayfa 6 Sayfa 7 Sayfa 8 Sayfa 9 Sayfa10 Sayfa 11
Vbn
et
-
-
Excel ~ C++ -
-
Exce
l
-
-
Vb
net
-
-
Delp
hi
-
C#ne
t
-
-
Delphi -
-
SQL -
-
Aspn
et
-
-
SQ
L
-
-
C++ -
Aspn
et
-
-
Window
s
~ Delp
hi
— C++ -
-
C#
net
~ Aspn
et
-
— -
-
— - — -
-
... -
-
... -
-
— -
Yukarıdaki tabloda sadece kitapad sütunu yazılmıştır. Bu kayıtların diğer
sütunlarının tamamı, sayfa içindeki satırlarda bulunmaktadır.
Veri Nasıl Açılır?
SQL Server; verileri iki yoldan birini tercih ederek açar.
1.YOL: Tablo içindeki tüm sayfaları tarar. Bu yönteme; table scan adı
verilir.
Bu yolu kullandığı zaman;
*** Tablonun başından taramaya başlar,
*** Tablo içindeki tüm sayfaları tek tek tarar,
*** Sorgulama sırasında verilen ölçütlere uyan kayıtlarıçekip, çıkarır.
3. 2.YOL: lndex veya index'ler kullanır. Bu yöntemi tercih ettiği zaman;
*** Sorgulama isteğine uyan satırlara; index ağaç yapısındaki yolu kullanarak kısa
yoldan ulaşır,
*** Verilen ölçütlere uyan kayıtları, çekip çıkarır.
SQL Server; sorgulamaya uyan kayıtları aramaya başlamadan önce, bir index olup-
olmadığını kontrol eder. Verilere ulaşmak için en iyi yolun, tabloyu taramak mı? Eğer
varsa index yapısını kullanmak mı? Olduğuna karar vererek verileri çekip, çıkarmaya
çalışır.
Bir lndex oluşturup- oluşturmamaya karar vermeden önce; index'in, table scan'dan
daha kullanışlı ve etkili olduğunu kabul etmek gerekir. Bunun için iki faktöre dikkat
edilmelidir; verinin yapısı ve sorgulamanın yapısı.
NEDEN İNDEXOLUŞTURULUR?
Index'ler verilere erişimi hızlandırır. Örneğin; kitapların sonunda index bölümleri
vardır. Herhangi bir konuyu aramak istediğiniz zaman kitap sonuna bakarak, hangi
sayfalarda olduğunu tespit eder ve kolaylıkla ulaşabilirsiniz. Eğer index olmasa idi, tek
tek sayfaları taramanız gerekirdi. Bu durum da, istediğiniz veriye ulaşmayı geciktirirdi.
Index hakkında aşağıdaki kural ve önerilere dikkat etmek gerekir:
*** lndex yapısı kullanılarak, birden fazla tablo ile yapılan sorgulamalar (join),
sıralama (şort) ve bilgilerin gruplanması(group) çok daha hızlı yapılabilir.
*** lndex oluştururken, aynı verinin birden fazla girişi engellenebilir. (unique)
*** lndex ile artan veya azalan yönde sıralama işlemleri oluşturarak, bunların
sürekliliği sağlanabilir.
*** Birden fazla seçim yapılan ve benzersiz kayıtların bulunduğu sütun veya sütun
topluluklarında; index yapısını kullanmak, verimliliği arttırır.
Tüm bunların yanısıra index oluşturmayı gerektirmeyen durumlar da olabilir.
,lndex'ler oldukça kullanışlı olmasına rağmen, ekstra disk alanı gerektirdiğinden ve
yapılandırılması için ek bir yönetici maliyeti getirdiğinden aşağıdaki durumlarda
kullanılmasa da olur.
*** lndex konulan sütunda çok fazla güncelleme yapıldığında SOL Server; ilişkili
index'leri güncellemeye çalışır. Index'ler oluşturulduktan sonra, devamlılığı için zaman
ve kaynak kullanırlar. Bunun için kullanılmayacak index oluşturmamak gerekir.
*** Eğer index konulan sütunda; çok fazla tekrar eden veri varsa, index yapısı fazla
avantaj sağlamaz.
4. INDEX MİMARİSİ:
lndex yapısını en etkili şekilde oluşturmak için, index mimarisini iyi bilmek gerekir.
Index mimarisi; birbirinden farklı olan clustered ve nonclustered index yapılarını
içerir.
SQL Server, bir clustered index tanımlanmadığı sürece veri sayfalarını; bir
küme(heap)şeklinde tutmaya devam eder. Yani, belli bir hiyerarşik düzen içermeyen
veri kümeleri ile veri sayfaları oluşur.
Veri kümelerinde lndex Allocation Map (IAM) kullanılabilir. IAM sayfaları:
*** Depolanan kümelerin devamının nerede olduğuna ait bilgileri içerir. Sistem
tablolarından sys.sysindexes, sys.partitions içinde; küme ile ilişkili ilk IAM sayfa
gösterici(pointer) bilgisi tutulur. Böylelikle başlangıç belirlenmiş olur.
*** Yeni bir satır eklendiğinde, kümeler içinde uygun ve boş bir satır olup
olmadığını IAM tespit eder.
*** Veri sayfalarına bağlanır. Veri sayfaları ve satırlar arasında özel bir hiyerarşi ve
sıralama yoktur. IAM sayfalarına kayıtlı olan, sadece mantıksal sayfalar arasında bağ
vardır.
Bir satır silindiği zaman, küme içinde yeni bir satır açılır ve burayı yeni bir veri
girişi için, elverişli hale getirir.
CLUSTERED INDEX:
Clustered index; sık sık arama yapılan ve sıralamaya tabi tutulan sütunlar için
kullanışlıdır.
Aşağıdaki temel kurallara dikkat etmek gerekir:
*** Her tablo, sadece bir adet Clustered İndex içerebilir. Tablonun içindeki
satırların fiziksel sırası ile index içindeki satırların sırası aynıdır.
*** Herhangi bir nonclustered index oluşturmadan önce, clustered index
oluşturmak gerekir. Çünkü bir fiziksel index, tablo içindeki satırların fiziksel sırasını
değiştirir.
Satırlar belli bir sıra ile sıralanır ve bu böyle devam eder. Örneğin; "ad" isimli bir
sütun olsun ve buna sacit, ali, veli, burhan kayıtları girilmiş olsun.
Eğer "ad" isimli sütunu clustered index ile yapılandırırsak o zaman, otomatik
olarak bu sıralama değişecek ve ali, burhan, sacit, veli veya veli, sacit, burhan, ali
olacaktır. Bu bizim seçimimize bağlıdır ancak, alfabeye göre bir sıralama söz konusudur.
*** Oluşturulan bir clustered index; ortalama olarak tablo boyutunun %5'i kadar
ekstra bir yeri, disk alanıüzerinde işgal eder. Ancak bu tamamen indexleme yapılacak
5. sütunun boyutuna bağlıdır. Örneğin: tablonuz disk üzerinde 20 MB yer kaplıyorsa;
clustered indexleme işleminden sonra 21 MB yer kaplayacaktır.
*** Bir satır silindiği zaman oluşan boşluk, yeni bir satır girişine izin verecek
şekilde, hazır bekler.
*** Clustered index oluşumu sırasında; geçici olarak disk üzerinde kullanılan bir
alan vardır ve bu alan tablo boyutunun %20'si kadardır. Örneğin; tablo boyutu 20 MB
ise, index oluştururken 4 MB'lık bir disk alanını geçici olarak kullanır. İşlem
tamamlandıktan sonra bu alanı, serbest bırakır. Bundan dolayı, index oluştururken
yeterli disk alanınızın olması gerekmektedir.
UYGULAMA:
1) Basit birörnekle savunduklarımızdan bazılarını ispatlamak için, şekildeki
tabloyu yüksel veri tabanı altında indexlebeni adı ileoluşturalım.
2) İçine şekildeki kayıtlar, girelim ve kaydederek çıkalım. Buradaki kavlarda ad
sütununa girilen değerler, hiçbir alfabetik sıra taşımamaktadır ve karışık olarak
girilmiştir. Bu bilgiyi unutmayalım.
6. 3) Oluşturduğumuz tablonun üzerinde sağ tuşa basarak, Design seçeneğine
tıklayalım ve tekrar sağ tuşa basarak Indexes/Keys seçeneğini seçelim.
7. 4) Gelen ekranda Add butonuna basalım ve Column namekısmından ad
sütununun seçili olduğunu kontrol edelim. Indexleme de kullanılacaksıralama A-Z
doğrultusunda olacağıiçin Ascendingdeğiştirmeyelim. Ardından clustered index oluşturmak:
için; Create as CLUSTEREDseçeneğini Yes yapalım ve Close butonu ile bu ekrandan çıkıp,
tablomuzu kaydederek, kapatalım.
5) Kayıtları tekrar görüntülediğimizde görüntü, şekildeki gibi olacaktır ve ad
sütununa göre sıralanacaktır.'' Burada anlatmaya çalıştığımız, sıralamanın nasıl
yapılacağını göstermek değil, Clustered index oluşturduğunuzda bunu otomatik olarak
yaptığını ve devam ettirdiğini göstermektir. Devam ettiğini ise yeni bir kayıt girerek
görebiliriz
8. NONCLUSTERED INDEX:
Bu tür index yapısına, bir tablo içinde birden fazla arama yapmaya ihtiyaç
duyuluyorsa başvurulur. Örneğin; Bir araştırmacının bir bitki kitabına; bitkilerin hem
halk arasında kullanılan ismine, hem de bilimsel ismine sık sık bakması gerekiyor. Bu
durumda, bilimsel isimler için; nonclustered index kullanırken, halk arasındaki isimler
için clustered index kullanabilir.
Nonclustered lndex oluştururken bilinmesi gerekenler;
*** Eğer index oluştururken tipi belirtilmez ise, otomatik olarak nonclustered tipi
olur.
SQL Server, mevcut nonclustered index'i aşağıdaki işlemler meydana gelince
yeniden yapılandırır.
Var olan clustered index silindiği zaman.
Bir clustered index oluştuğu zaman.
Clustered index olarak tanımlanmış bir sütunu, Drop_Existingseçeneği ile
değiştirmeye çalışıldığı zaman.
***Nonclustered index içindeki verilerin (Leaf level) sıralanması ile tablonun
fiziksel sıralaması birbirinden farklıdır. Leaf level sıralaması artan yönde bir
sıralamadır(Ascending).
*** Cluster anahtarları ve satır tanımlamaları ile benzersiz kayıt girişi sağlanabilir.
*** Her tabloda maksimum 249 adet nonclustered index olabilir.
*** Nonclustered index'den önce, cluster index oluşturmak gerekir.
*** Çok fazla seçim yapılan kayıtlar üzerinde kullanılabilir.
"** Satırların satır tanımlayıcıları mantıksal bir sıraya sahiptir ve Satır İD; sayfa
numarası ve satır İD bilgilerini içerir.
SQL SERVER. BÜNYESİNDEKİ VERİLERE NASIL ERİŞİR?
9. Güçlü bir veri tabanı tasarımı için; SQL Server'ın verilere nasıl eriştiğini anlamak
gerekir. Bu bölümde bu yapıyı inceleyeceğiz.
SOL SERVER. SYSINDEXES TABLOSUNU NASIL KULLANIR?
SQL Server içinde bulunan sysindexes sistem tablosu; tablolar ve indexler
hakkında en önemli bilgilerin tutulduğu merkezi yerdir. Tablo içinde bulunan verilere
nasıl ulaşılacağına dair bilgileri tutar ve istatistik bilgileri içerir.
Örneğin; Her bir tablo içindeki veri sayfaları ve satırların sayısı gibi...
Bu tablo içeriğini görüntülemek için aşağıdaki ifadeyi yazmanız yeterlidir.
Select * from sys. Sysindexes
Sonuçta, şekildeki liste karşımıza çıkar;
id sütunu; her bir tablo ve index için kimlik numarası taşır. Bunlar benzersiz olup,
tek bir tabloyu ifade eder. Diğer önemli bir sütun ise, nesnelere ait özellikleri tutan indid
sütunudur.
10. Bu sütundaki rakamların ifade ettikleri;
*** Eğer bir bilgi kümesi, sysindexes tablosu içinde sadece bir satıra sahipse, bu
sütunun değeri "O" olur. First IAM sütunu; tablo içinde bulunan sayfalar için IAM sayfa
zincir bilgilerini tutar. Sayfalar birbiri ile ilişkili olmadığı için SQL Server mutlaka IAM
sayfalarını kullanarak, veri sayfalarına erişebilir.
*** Bir tablo içinde eğer bir clustered index oluşturulmuş ise indid "1" değerini
alır. Clustered index'in en üst bilgisi root sütununda tutulur. Balanced tree (B-Tree).
*** Bir tablo için oluşturulan her nonclustered index bilgisi 2-250 arasında
alacağı değer ile indid sütununda tutulur. Nonclustered index'in en üst bilgisi root
sütununda tutulur (B-Tree).
*** Eğer indid sütununda 255 yazıyorsa bunun anlamı; tablonun en az bir adet
text, ntext veya image sütununa sahip olduğudur.
INDEX KULLANILMADAN SATIRLARIN BULUNMASI:
Eğer bir tablo index taşımıyorsa o zaman SQL Server, bilgilere erişmek için table
scan yapısını kullanır. Yani, tüm tabloyu tarar. SQL Server, IAM sayfasını bulmak için
sysindexes tablosunu kullanır. IAM sayfası; tabloda ilişkili tüm sayfaların listesini
içerir. Bu liste sekizer sayfalık kümeler halindedir ve Extend olarak adlandırılır.
Bu bilgiye ulaştıktan sonra SQL Server, tüm veri sayfalarını okuyabilir. Bu yapının
büyük bir tabloda az bir bilgi döndürecek sorgulamalar için ideal olmadığını bir daha
hatırlatmak isterim.
Bulunan satırlar, sırasız olarak döner. Başlangıç yapısında sıralı olsa bile bu böyle
devam etmez, yani sıralı yapı korunmaz.
NONCLUSTERED INDEX ile SATIRLARIN BULUNMASI:
id İndid=2 root
11. Select soyad, ad from uye where ad between ‘nurcan’ and ‘nursel’
Select ifadesinde kayıtları bulurken, nonclustered index yapısının işleyişşeması,
yukarıdaki şekilde verilmiştir.
Nonclustered index; bir kitaptaki index kısmı gibidir. Kitap içinde veriler; ayrı bir
yerde ve genellikle sonda bulunan index bilgileri de ayrı bir yerde tutulur.
Nonclustered lndex yapısı da, aynı kitap gibidir. Yani veri ayrı yerde, index ayrı
yerde bulunur. Tablo ile ilgili bilgiler; index yapısındaki işaretçilerle (pointer)
belirlenir.
SQL Server indexleri; B-tree gibi yapılanmıştır. Her index; içinde bulunan
sayfalardaki satırlar ile bir sonraki ilişkili sayfalara veya veri satırlarına ait bilgileri
tutar.
Index içindeki her bir sayfa, index node olarak adlandırılır. B-tree yapısının en
üstündeki düğüme root node veya root level, alttaki düğüme ise leaf node veya leaf
level adı verilir. Root ve Leaf düğümleri arasında bulunan herhangi bir seviye, orta
seviyedir. Orta veya alt seviye içindeki her bir sayfa; bir Pointer'a sahiptir. Bu Pointer,
bir üstten gelen ile bir sonraya gidecek yol hakkında; sayfalar arasında çiftli bir link
oluşturur.
Eğer bir tablo sadece nonclustered index içeriyorsa o zaman, Leaf düğümünde
veri satırlarının değerlerini tutan; satır göstericileri vardır. Bunlar Pointer'larla nereye
gidileceği hakkında yardımcı olur. Her bir pointer(Row İD veya RID); sayfa üzerindeki
satır sayısı, sayfa numarası ve dosya İD bilgilerini bulundurur.
12. CLUSTERED INDEX ile SATIRLARIN BULUNMASI:
Select soyad, ad from uye where ad between ‘nurcan’ and ‘nursel’
Select ifadesinde kayıtları bulurken clustered index yapısının işleyiş şeması,
yukarıdaki şekilde verilmiştir.
Clustered index ve Nonclustered index; birbirine benzeyen B-tree yapısını
kullanılırlar.
Ancak aralarındaki farklar, aşağıdaki gibidir:
*** Clustered index'in veri sayfalarıB-tree yapısının leaf düğümündedir. ***
Clustered index içindeki veri satırları sıralıdır ve Cluster Key üzerinde belli bir sıra
içinde tutulurlar ve bu sıra yapısı, her zaman korunur.
*** Bir telefon rehberine benzeyen Clustered lndex sayesinde, aynı harf ile
başlayan isimler, aynı sayfada olduklarından çok hızlı bir şekilde verilere ulaşılır. Ancak
bir tablo için; sadece bir adet clustered index olabileceğini unutmayalım.
*** Aynı tabloda hem clustered index, hem de nonclustered index varsa ilk önce
noncluster yapısında leaf level bazına kadar arama indirgenirken, aynı kayıdın
clustered index bilgisi ile clustered index kısmına yönlendirme yapılarak, aranılan
kayıtlar daha hızlı bulunabilir. Bunun için bir tabloya ilk önce clustered key, ardından
eğer ihtiyaç duyuyorsanız nonclustered key koyunuz.
id İndid
=2
root
Ayabakan
---
Demirli
NON CLUSTERED
INDEX
Aybakan
13. ad,soyad,yas from uye where soyad=’İnan’
Select ifadesinde soyad sütunu için nonclustered, ad
sütunu için ctustered kullanıldığında, yardımlaşmalarışekildeki gibidir.
TRANSACT-SQL İLE INDEX:
Şu ana kadar incelediğimiz index yapılarını kod ile nasıl oluşturacağımızı ve
oluşturulan index bilgilerinde nasıl değişiklik yapacağımızı bu bölümde inceleyeceğiz.
Burada klasik ve eski sürümlerden gelen index yapısı üzerinde duracağız ve bu
konunun sonunda ise SQL Server 2005'den itibaren yapısında oluşan değişiklikleri ayrı
bir başlık altında inceleyeceğiz. Böylelikle size mukayese
olanağı sağlamış olacağız.
INDEX OLUŞTURMA ve SİLME (CREATE !NDEX- DROP INDEX):
lndex oluşturmak için CREATE INDEX, silmek için ise DROP INDEX
ifadeleri kullanılır. Her iki ifadeyi de kullanmak için, tablonun sahibi olmak gerekir.
CREATE INDEX ifadesi ile index oluşturulacağı gibi, SQL Server SQL Server
Canakatan
----
Demirli
İnan
----
Ayaba
kan
Kema
l
Canak
atan
Gürse
l
Demi
rli
Nihat
Bana
bakan
Tunca
y
Cazgı
r
Fatih İnan Yükse
l
Buzab
akan
Hale ---- ---- ----- ----
Ayşe
----
Yüksel
CLUSTERE
D
INDEX
Ayşe Yanar --- ---- --- ---
Bayha
n
Bak ---- --- Yüksel İnan
--- --- ---- --- --- ---
14. Management Studio içinden Tools menüsünden Database Engine Tuning Advisor
seçeneği ile de index oluşturulabilir. Bu ikinci seçenek ayrı bir başlık içinde bu konuda
incelenecektir.
Index oluştururken, aşağıdaki durumlara dikkat etmek gerekir;
*** Primary Key veya Unique Constraint oluşturulduğu zaman index, otomatik
olarak oluşur. Standart index oluşturmak yerine, Primary Key veya Unique Constraint
tercih edilmelidir.
*** Create lndex ifadesini kullanabilmek için; tablonun sahibi olmak gerekir.
*** View nesneleri üzerinde de index oluşturulabilir.
*** SQL Server, index bilgilerini sysindexes sistem tablosunda tutar.
*** Bir sütun üzerinde index oluşturulmadan önce, daha evvel bir index'e sahip
olup- olmadığı araştırılmalıdır.
*** Daha etkili kullanmak için; index boyutlarını küçük tutmak gerekir. Bir
Ciustered lndex oluşturulduğu zaman, mevcut tüm nonclustered index'ler yeniden
yapılanır.
Basit index yazılımı, aşağıdaki şekildedir:
CREATE [UNIQUE] [CLUSTEREDNONCLUSTERED]
INDEX index_adi ON {tablo_adı view_adı} (sütun_adi(ASCDESC])
[WITH
[PAD INDEX]
[[,]FILLFACTOR=fiilfactor]
[[,]IGNORE_DUP_KEY]
[[,]DROP_EXISTING]
[[,]STATISTICS_NORECOMPUTE]
[[,]SORT_IN_TEMPDB]
][ON dosyagrubu_adı]
15. Silmek için ise DROP INDEX ifadesi kullanılır.
Bu ifade kullanılırken dikkat edilmesi gereken durumları, listeleyecek olursak;
*** lndex silindiği zaman SQL Server, kullandığı disk alanını serbest bırakır.
*** Primary Key veya Unique Constraint sonucu oluşan index'i silemeyiz. Bunu
gerçekleştirmek için; Primary Key veya Unique Constrant'i tamamen silmemiz
gerekir.
*** Bir tabloyu sildiğimiz zaman, bu tabloda bulunan tüm index'ler silinir.
*** Bir Ciustered lndex silindiği zaman, tablo içinde bulunan tüm Nonclustered
lndex'ler yeniden yapılanır.
*** Drop lndex ifadesini, sistem tablolarında kullanamayız. Kullanım şekli,
aşağıdaki gibidir;
DROP INDEX tablo_adı.index_adı veya [view_adı.index.adı]
UYGULAMA:
1) Aşağıdaki şekildeki gibi görkem veri tabanı içinde; müşteriler ısımli tabloyu
oluşturalım.
2) Aşağıdaki kayıtları girelim.
3) Şimdi bu tabloda kod ile bir index oluşturalım. Bunun için SQL Query Editör
16. içine aşağıdaki kodu yazalım. Aşağıdaki kod ile müşteriler tablosunda bulunan
"musterino" isimli sütun üzerinde, Ciustered lndexoluşturuyoruz.
Use görkem
Create clustered index cl_musterino
On musteriler (musterino)
4) Yukarıdaki kodu çalıştırdığımızda, aşağıdaki mesaj ile karşılaşırsak, işlem başarı
ile tamamlanmış demektir.
5) Tablonun tasarım kısmında iken Fare'nin sağ tuşuna basarak lndexes/Keys
seçeneğine tıkladığımızda şekildeki ayarlar karşımıza gelir. Bu şekil bize, index olayının
başarı ile gerçekleştiğini belirtmektedir Burada musterino'ya göre; otomatik artan
yönde ASCl sıralama yapıldığına dikkat ediniz. Siz numaraları karışık girseniz bile o,
otomatik olarak sıralayacaktır. Index olan bir sütun; mükerrer kayıt girişine izin verir.
Eğer Is Unique -» Yes değişikliği yaparsanız o zaman mükerrer kayıt girişine izin
vermez.
6) Oluşturduğumuz; cl_musterino isimli index'i silmek için aşağıdaki kodu
yazalım.
Use görkem
18. tekrar edilemez. Yani aynı veriden sadece bir kez girilebilir. Eğer tabloda bir Primary
Key veya Unique Constraint varsa SQL Server, otomatik olarak Unique lndex oluşturur.
Hem Clustered lndex, hem de Nonclustered lndex yapılarında kullanılabilecek bu
özellik için, dikkat edilecek hususları listeleyecek olursak;
*" Eğer tabloda veri varsa ve index oluştururken veya sonradan Unique özelliği
kazandırılıyorsa SQL Server, önceki kayıtlarda tekrar edilen kayıtların olup- olmadığını
kontrol eder varsa, hata verir.
*** Yeni kayıt girerken veya bir kayıt üzerinde değişiklik yaparken, eğer bu kayıt
mükerrerse, hata oluşur.
*** Sadece aynı olmasını istemediğiniz sütunlara; bu özelliği kazandırmak gerekir.
Örneğin, isimlerden oluşan bir sütuna bu özelliği kazandırmak mantıksızdır. Çünkü aynı
isimden birden fazla olabilir.
UYGULAMA:
1) Şimdi mükerrer kayıt girilmesini engellemek için, unique index oluşturalım.
Use görkem
İf exists (select name from sysindexes where name= ‘cl_musterino’)
Begin
Drop index musteriler.cl_musterino
Print ‘silindi’
End
Create unique nonclustered index cl_musterino
On musteriler(musterino)
2) Çalıştırdıktan sonra aynı müşteri numarasından oluşan, bir kayıt girmeye
çalışın, bu işlemin gerçekleşmediğini göreceksiniz. Unique index oluştururken eğer
tabloda daha önce aynı müşteri no'larından varsa, hata verecek ve unique index
oluşturmayacaktır. Bu işlemi ilk tekrarda yapacaktır. Eğer sadece aşağıdaki gibi
yazarsak bize o numaradan kaç adet olduğunu, yanına yazarak gösterir.
19. 3) Aşağıdaki kodu yazarak, oluşturduğumuz index'i silelim.
Drop index musteriler.cl_musterino
4) Tablomuzun musterino kısmına iki adet daha 101 ve bir adet 102 no'lu kayıtları,
mükerrer olarak ekleyelim.
5) Şimdi tekrar index oluşturmaya çalışalım ve aşağıdaki kodu yazalım.
Create unique noncluster index cl_musterino
On musteriler (musterino)
6) Çalıştırdığımızda SQL Server; kayıtları kontrol edecek ve ilk tekrar kayıdı
gördüğü anda, bu işlemin gerçekleşemeyeceğini bildiren, aşağıdaki mesajı karşımıza
çıkaracaktır. Dikkat edilirse, ilk tekrarlanan kayıt 101 olduğu için hata mesajında bu
kayıdın uyarısı, belirtilmektedir.
20. 7) Bu gibi durumlarda kayıtlarınızın sayısı çok fazla olabilir ve hangi kayıttan ne
kadar mükerrer var? Bunu bir liste şeklinde görüp, önlem almak isterseniz aşağıdaki
kodu yazmanız gerekir.
Select musterino, count (musterino) as tekrarlananlar
From musteriler group by musterino
Çalıştırdığımızda görüntü, şekildeki gibi olacaktır.
8) Ancak tekrarların olması için değerin 1'den büyük olması gerekir. O zaman
sadece tekrarlananları görmek için aşağıdaki kodu yazmak gerekir. Grup yapıldığı
zaman where yerine, koşul için having komutu kullanılır.
Select musterino, count (musterino) as tekrarlananlar
From musteriler group by musterino
Having count (musterino)>1
Order by musterino
Çalıştırdığımızda görüntü, şekildeki gibi olur.
BİRLEŞİK (COMPOSİTE) INDEX:
Bir tabloda istenirse, birden fazla sütunu kapsayan index oluşturulabilir. Buna
Composite Index adı verilir. Birden fazla sütunun, tek bir key değeri altında toplanma
işlemidir. Bu, ayrı ayrı verilen index'ler ile karıştırılmamalıdır.
21. Eğer bir veya daha fazla sütunu daha iyi bir arama için; tek bir key altında
toplamak istiyorsak ve index içinde tek bir sütunu referans olarak kullanmak istiyorsak,
tercih edeceğimiz bir yöntem olabilir. Bunu yine bir telefon rehberi ile açıklayacak
olursak; telefon rehberlerinde arama yapılırken, aynı soyadına sahip daha az kişi
bulunduğu için, soyadına göre arama yapılır. Bizim arama şeklimiz; önce aramak
istediğimiz kişinin soyadları kısmına bakarak gelişir, soyadları bloğuna ulaştıktan sonra
ikinci arama kriterimiz isim bazlı gelişir ve aradığımız kişiyi bulduktan sonra, artık
telefon numarasına erişim işlemimizi tamamlayabiliriz. İşte composite index, bu yapıya
çok benzer ve ilk arama kriterinden sonra ikinci kritere göre istenilen kayıtlar, hızlı bir
şekilde listelenir.
Burada index oluştururken yazma sırası çok önemlidir. İlk önce yazılan;
önceliklidir ve ilk olarak o grubu bulur. Ardından diğer sütuna göre arama yapılır.
Bunun için; daha az kullanman kayıtlara ait sütun ilk olarak tercih edilmeli, ardından
diğer sütunlar gelmelidir.
Bunun dışında dikkat edilmesi gereken hususlar:
*** Tek bir Composite index yapısında; en fazla 16 sütun bulunabilir. Composite
index'i oluşturan sütunların toplam genişliği; en fazla 900 byte olabilir.
*** Composite index'i oluşturan tüm sütunlar; aynı tablo içinde olmalıdır. Ancak
view nesnesi içinde oluşturulacak ise, farklı tablodan sütunlar içerebilir.
*** Birden çok sütunda index özelliğine nazaran, aynı key içinde birden fazla
sütun barındıran index'ler, daha kullanışlıdır.
*** Sorgulama performansını arttırırken, tabloda kullanılacak index sayısını azaltır.
Not: Aynı sütun için birden fazla index oluşturmak, çok kullanışlı bir yapı değildir.
UYGULAMA:
1) Aşağıdaki kodu SQL Query Editör içine yazarak, tek bir index yapısı içine iki
sütunu koyarak composite index oluşturuyoruz. Burada ilk sütun olarak musterino ve
ikinci sütun olarak mad sütununu referans olarak alıyoruz. Index türü olarak; clustered
index yapısını kullanıyoruz. Bunun anlamı; musterino altında bulunan kayıtlar, ilk önce
küçükten büyüğe sıralanacak, musterino bilgileri aynı olan mad sütunları da kendi
aralarında a harfinden z harfine doğru ikinci bir sıralama yapacak. Yani iki grupta da
sıralama söz konusu olacak.
Create unique clustered index cl_musterino
On müsteriler(musterino,mad)
2) Çalıştırdığınız zaman kayıtların görüntüsü, şekildeki gibi olacaktır.
22. 3) Tablomuzun tasarım kısmından lndexes/Keys kısmına geçtiğimizde görüntü,
şekildeki gibi olacaktır.
Burada dikkat edilirse Create UNIQUE kutusu dolu, yani benzersiz bir index
oluşturduk. Ancak 101 ve 102 no'lu kayıtlar mükerrer olmasına rağmen, hata vermedi.
Bunun sebebi:
Bu kontrol artık iki sütuna göre yapılıyor, yani mükerrer kayıt kavramı; eğer
"musterino" ve "mad" sütunlarının her ikisi de aynı olursa, hata mesajı veriyor. Onun
dışında bu sütunlardan herhangi birine, istenildiği kadar mükerrer kayıt girilebilir.
4) exec sp_helpindex müşteriler satırı ile index'iniz hakkındaki bilgileri
görüntüleyiniz.
Exec sp_helpindex musteriler
23. INDEX SEÇENEKLERİ :
SOL Server;çeşitli index seçenekleri sunarak, oluşturmayı planladığınız
İndexperformansın, arttırmanız, sağlar. Bu kısımda, bu seçenekler, kullanarak nasıl
index oluşturacağımızı inceleyeceğiz.
FİLL FACTOR:
Clustered ve Nonclustered index yapılarında kullanabileceğimiz bu yapı ile
INSERTve UPDATE ifadelerinde performans, yükseltebiliriz. Bir index sayfası dolduğu
zaman, yeni gelen satırlar, koymak .çın SQL Serler sayfa bölümlenmesi yöntemine
başvurur(Page splı) FILL FACTOR kuLlanarak, leaf-level kısmında bolumlenen
sayfalardaki boşluk miktarı, belirlenir.
FILLFACTOR; sadece index oluşturulurken veya yeniden yapılandırılırken
uygulanabilir. Sonradan dinamik olarak değiştirilemez.
Fillfactor için belirleyeceğiniz değer, genel olarak ne kadar sıklıkla verilerinizi
güncellediğinize ve yeni kayıt eklediğinize bağlıdır.
Genellikle OLTP işlemlerinde düşük fillfactor değeri kullanmak gerekir. Ana£
servis işlemlerine tabii tutulacak durumlarda ıse; yüksek fillfactor tercih edilmelidir.
“0" savılan değerdir ve anlamı; sayfanın %100 dolu olması demektir.Bu değer “1-
99” arasında bir değer ile sayfalardaki doluluk oranınıbelirtir.Klasik sorgulama
işlemlerinde bu değer seçilmelidir. "100" değeriise aynı"0" gibidir ve doluluk oran,
tamdır. Analız işlemlerinde bu, tercihedilmelidir.
24. Kısaca özelliklerini ve dikkat edilmesi gereken hususlar, listeleyelim;
***"1" ile "100" arasında bir değer alabilir.Default değer "0"dır ve tam doluluk
sağlar. Kod ile fillfactor e, 0 değeri atanamaz.
***sp_configure sistem stored procedure'ü kullanılarak; default fillfactor
değeri değiştirilebilir.
*** Burada verilen değer; yüzdesel olarak doluluk oranını belirtir. Örneğin: 70 değeri atandığında
%70'lik kısmında veriler olacak ve %30'luk kısmı bos olacaktır. Bu boşluk, tabiiki yeni
kayıtlar için, hazır durumda beklemektedir.
*** Bu değer, eklenen kayıt sıklığına göre ayarlanmalıdır. Ne kadar çok kayıt
ekleme sıklığı varsa, bu değerin o kadar düşük olması tercih edilir.
PAD INDEX:
Non-leaf level bölgesindeki bölümlenme yüzdesini belirler. Bunun
kullanılabilmesi için ilk önce fillfactor seçeneğinin aktif hale getirilmesi, 1-99 arasında
bir değere sahip olması gerekir. Fillfactor ile leaf level kısmındaki sayfa bölünme
boşluk oranını belirlerken; eğer pad_index seçeneğini aktif hale getirirsek aynı oran,
burası için de geçerli olur. Fillfactor değeri ne olursa olsun, non-leaf level index
sayfasındaki öğelerin değeri 2'den az olamaz. Bunun aktif hale getirilmesine en büyük
etken; veri tabanında çok fazla değişiklik ve yeni kayıt ilavesi yapılmasıdır.
UYGULAMA:
1) lndex oluştururken Pad_index ve fillfactor aktif hale getirilebilir. Aşağıdaki
örnekte, "müşteriler" tablosundaki "musterino" sütununa index özelliği kazandırılıyor.
Index sayfalarının doluluk oranı %70 olarak belirleniyor, fiilfactor ile belirlenen bu
oran, leaf-level index sayfaları için geçerlidir. Eğer pad_index seçeneğini ilave
etmeseydik, o zaman non-leaf level bölgesindeki index sayfaları, her zaman dolu olarak
kalacaktı.
Use gorkem
25. If exists (select name from sysindexes where name=’cl_musterino’)
Begin
Drop index musteriler.cl_musterino
Print ‘silindi’
End
Create index cl_musterino
On musteriler (musterino)
With pad_index ,fillfactor=70
2) Çalıştırdığınız zaman şekildeki gibi verdiğimiz ayarlar, müşteriler tablosuna
uygulanacaktır. Burada nonclustered index aktiftir.
Çünkü oluştururken index türü belirtilmez ise, nonclustered index olur.
INDEXLERİN KONTROLÜ ve BAKIMI:
Bir index oluşturduktan sonra onu en yüksek performans ile kullanmak gerekir.
Belli bir süre sonra veriler, bölünüp parçalanabilir.
26. Bunun için yeni teknolojiler SQL Server 2005'den itibaren geliştirilmiştir. Bunları
konu sonunda; yenilikler kısmında bulabilirsiniz.
Bunun dışında SQL Server içinde bulunan çeşitli seçenekler ile index'leri veniden
yapılandırabilir ve performansını iyileştirebiliriz. Bu kısımda, bu geçenekleri
inceleyeceğiz.
VERİLERİN BÖLÜNMESİ:
İş yapısına bağlı olarak verilerin parçalanması, iyi veya kötü performansa 'yol
açabilir. Verilerin bölünmesi, yapılan değişiklikler sonucu meydana gelir. Yeni kayıt
eklendikçe, silindikçe veya index sütunlarındaki değerler değiştikçe, veri parçalanmaları
kaçınılmaz hale gelir. Page Split olarak adlandırdığımız bu yapı; Disk üzerinde kaplanan
alanı arttırırken, sorgulama süresini uzatır.
Bölünme mekanizmalarını yönetmek için; klasik SQL Server içinde 2 föntem vardır.
Birinci yöntem: Mevcut index'i silerek yeniden index ve BJIfactor oluşturmaktır. İkinci
yöntem ise: Mevcut index ve fillfactor üzerinde değişiklik yaparak, yeniden
yapılandırmaktır.
Bölünme, OLTP yapısı için yararlıdır. Çünkü bu yazma tabanlıdır ve ne kadar geniş
alan olursa, o kadar rahat yazar. OLAP için ise zararlıdır. Çünkü bu okuma tabanlıdır.
DBCC SHOWCONTIG:
Bu ifade ile tablo üzerinde bulunan, veri ve index üzerindeki bölünme bilgilerini
elde edebiliriz. Bu komut çalıştığında veri ve index sayfalarının, dolu olup- olmadığını ve
bölümlenme bilgilerini üretir.
Temel olarak sysyindexes sistem tablosunu temel alarak, belli süre periyotları için
bilgileri döndürür.
Select * from sys.sysindexes
UYGULAMA:
1) Aşağıdaki komut ile tablo hakkında genel bilgi alırız. Eğer bir index için
bilgi edinmek istersek, virgülden sonra bunu belirtmemiz gerekir.
Dbcc showconting (musteriler)
Veya
Sbcc showconting (musteriler, cl_musterino)
27. 2) Çalıştırdığımızda aşağıdaki sonuçlar, tablo bazlı sorgulamada
karşımıza gelir.
Yukarıda bulunan parametreleri kısaca açıklayalım;
*** Page Scanned: Tablo veya index içindeki sayfa sayısı.
*** Extents Scanned: Tablo veya index içindeki extent sayısı.
*** Extent Switches: Extend sayfalarında dolaşma sayısı.
*** Avg Pages per Extend: Sayfa zinciri içindeki her bir extent içinde bulunan
sayfaların sayısı.
*** Scan Density: Eğer bu değer, %100 ise her şey tamam demektir. 100'ün
altında değer almaya başlarsa o zaman, bazı bölünmeler meydana gelmiş demektir.
*** Extent Scan Fragmentation: Taranan index leaf sayfalarındaki extent'lerin
bölünme oranı.
*** Avg.Bytes Free per Page: Her sayfada bulunan, ortalama boş bayt miktarını
gösterir.
*** Avg. Page Density(full): Ortalama sayfa yoğunluğu.
DBCCINDEXDEFRAG:
Tablo içindeki verilerde meydana gelen değişikliklerde, tablo içinde bulunan index
sayfaları bölünebilir. DBCC INDEXDEFRAG ifadesi ile tablo ve view üzerinde bulunan
clustered ve nonclustered leaf level index sayfaları birleştirilir. Bu yeniden sıralama,
index tarama performansını arttırır.
UYGULAMA:
1) Aşağıdaki ifade çalıştırıldığında birleştirme gerçekleşerek, sayfalar yeniden
düzenlenir.
Dbcc indexdefrag (gorkem, musteriler, cl_musterino)
2) Sonucunda taranan sayfa, taşınan sayfa ve silinen sayfa bilgileri karşımıza gelir.
28. DROP EXISTING:
lndex'lerin karakteristik yapısını değiştirmek veya index'leri silmeden yeniden
yapılandırmak için kullanılan ifadedir.
En önemli yararlarından biri; PRIMARY KEY veya UNIQUE Constraint içinde
oluşan, index'leri de yapılandırmasıdır.
Leaf level sayfaları yeniden yapılandırarak sıkıştırabilir, genişletebilir veya
bölünmeleri silebilir. Index istatistiklerini yeniden hesaplar.
Değiştirilebilecek index karakterlerini, bir liste şeklinde sunalım;
Tip:
*** Noncluster index, cluster index'e dönüştürülebilir.
*** Cluster index, nonclusterindex'e dönüştürülemez.
Index Sütunları:
*** Tanımlanmış index sütununu, başka sütunlar ile değiştirilebilir.
*** Composite index yapısında bulunan bir sütun silinebilir veya yeni bir sütun
eklenebilir.
*** lndex sütununa unique özelliği kazandırılabilir veya bu özellik varsa, iptal
edilebilir.
29. Seçenekleri:
— FILLFACTOR veya PAD_INDEX değerleri değiştirilebilir.
Aşağıdaki yazılım ile daha önce oluşturduğumuz "musterino" sütununda bulunan
nonclustered index yapısını, clustered index yapısına çeviriyoruz. Tipini unique ve
fiilfactor değerini %65 yapıyoruz. Eğer çalıştırdığınızda hata olursa, tablonuzda
bulunan "musterino" sütununda mükerrer kayıt var demektir. Bunun için, unique
parametresini kaldırarak çalıştırınız.
Use gorkem
Create unique clustered index cl_musterino
On musteriler (musterino)
With drop_existing, fillfactor=65
UYGULAMA:
1) Aşağıdaki kodu yazarak, yeni bir index oluşturacağız. Bu kod; eğer aynı isimli
müşteriden daha önce oluşturulmuş ise onu silerek, yeniden oluşturur. Böylelikle hata
oluşmasını önler.
Use gorkem
Set nocount on go
If exists
(select name from sysindexes where name = ‘cl_musterino’)
Drop ındex musteriler.cl_musterino
Go
Create nonclustered ındex cl_musterino
On musteriler (musterino)
With fillfactor=75
Go
Set nocount off
Go
2) İşlem sonucunda ayarlar kısmındaki görüntü, şekildeki gibi olur.
3) Eğer bir index'in oluşup oluşmadığı kontrol etmek istersek, aşağıdaki kodu
yazmamız gerekir.
30. Select name
From sysindexes
Where name ın (‘cl_musterino’)
Go
Set nocount off
4) Çalıştırılınca şekildeki ifade ile karşılaşırız.
1) Bir tabloda bulunan tüm index'leri listelemek istersek;
6) Aşağıdaki yazılım ilemüşteriler tablosu hakkında, yer kullanım bilgileri elde
edebilir. Çalıştırdığımızda görüntü, şekildeki gibi olacaktır.
Exec sp_spaceused musteriler
7) Aşağıdaki yazılım ise müşteriler tablosuna ait bilgileri, sysyindexes
tablosundan alarak gösterir.
31. Select* from sysindexes where id=object_id (‘musteriler’)
STATİSTİCS:
Statistics bilgiler, bir index veya bir sütun için uygulanabilir. Bu kısımda, bunları
nasıl gerçekleştireceğimizi inceleyeceğiz.
STATİSTİCS OLUŞTURMA ve GÜNCELLEME:
İstatistik bilgiler, sysyindexes tablosu içinde bulunan statblob sütununda tutulur.
Image veri tipine sahip bu sütunda bulunan bilgiler;
İstatistiklerin en son güncellendiği, tarih ve saat.
Tablo içindeki satırların sayısı.
Histogram ve Density bilgileri.
Ortalama key uzunluğu.
Histogram yapısında benzersiz değerler.
Statistics, otomatik veya manuel olarak oluşturulabilir.
Otomatik Olarak Oluşturmak İçin:
Veri tabanı üzerinde sağ tuşa basılarak Properties seçeneğine tıklanır ve gelen
iletişim kutusundan Options sayfasına geçilerek, Auto Create Statistics değeri True
yapılır. Varsayılan olarak bu zaten True değerindedir. Otomatik Statistics devreye
sokulduğu zaman, index sütununda bulunan veriler ve index'siz sütunlardan JOIN veya
32. VVHERE ifadesi kullananların istatistikleri, otomatik olarak oluşturur.
Manuel Oluşturmak İçin:
CREATE STATİSTİCS ifadesi ile manuel olarak, istatistik bilgileri oluşturulabilir. Bu
ifadeyi kullanabilmek için, mutlaka tablonun sahibi olmak gerekir.
Oluşturabileceğimiz istatistik seçenekleri;
*** lndex'lenmemiş sütunlar,
*** Composite index içindeki ilk sütun dışında kalan sütunlar,
*** Koşul verilmiş computed sütunlar,
***Image, text ve ntext veri tiplerine sahip olmayan sütunlar.
Kullanım sekli;
33. Create statistcs istatiktik_ismi on (tablo_adı veya view_adı)(sütunadı)
Belirlenen süre ve olaylar sonunda SQL Server, Statistics bilgilerini günceller. Bu,
sütun sayısı veya index sayfa sayısı olabilir.
Otomatik Statistics güncellenmesi, için; veri tabanı özelliklerinden Auto Updates
Statistics seçeneği True yapılır.
UPDATE STATİSTİCSkomutu ile manuel olarak, Statistics güncellenebilir.
Aşağıdaki durumlarda istatistiklerin güncellenmesi gerekebilir;
*** Tablo içine herhangi bir kayıt girmeden önce index oluşturulacaksa,
*** Tablo truncated ise,
*** Çok az aynı tür veri içeren birçok kayıt, tabloya ekleniyorsa.
Kullanım sekli;
Update statistcs tablo_adı veya view_adı index_adı veya istatistik adı
STASİSTICS GÖRÜNTÜLENMESİ:
Bir index veya bir sütun hakkındaki istatistik bilgileri, DBCC
SHOW_STATISTICS ifadesi ile görüntüleyebiliriz.
34. Alınacak bilgilerin bazıları;
Sütun adı Açıklama
İstatistiklerin en son güncellenen, tarih ve saati.
Tablo içindeki satırların sayısı.
İstatistik bilgiler için, satır örnek sayısı.
Dağıtılmış adım sayısı.
ilk index sütununun yoğunluğu (Kullanılma sıklığı)
İlk index sütununun ortalama uzunluğu.
Index sütunlarının yoğunluğu (Kullanım sıklığı)
lndex sütunların uzunluğu.
Kullanım Şekli :
Dbcc show_statıstıcs (‘tablo_adı, index_adı’)
Aşağıdaki ifadeyi yazarak sonuçları gözlemleyiniz
Updated
Rows
Rows
Sampled
Steps
Density
Average
key length
Ali
density
Average
length
35. Dbcc show_statıstıcs (‘musteriler’, cl_musterino)
SYSYINDEXES TABLOSUNUN SORGULANMASI:
Statistics için en önemli kaynak hiç kuşkusuz, sysyindexes tablosudur. Aşağıdaki
tabloda, sütunların açıklaması verilmiştir.
Açıklama Değer
Alabileceği değerler;
0 nonclustered table
1 clustered index
1-249 nonclustered index
255 text, image, ntext
Indid değeri 0-1 arası veri sayfalarının kullanım sayısıdır.
Indid=255 ise dpages=0
Diğer durumlarda noncluster index
sayfalarının kullanım sayısıdır.
Indid' e göre çeşitli anlamlar ifade eder.
Indid' e göre çeşitli anlamlar ifade eder.
Bu değer, yeniden index
oluştururken veya yapılandırırken,
fillfactor değerini hatırlamamızı
sağlar.
Minlen Bir satırın en küçük boyutu. Sayısal
Xmaxlen Bir satırın en büyük boyutu Sayısal
Sütu
n
lndex tipini gösterir.Indid
Leaf-level
index sayfalarının
sayısı
Dpages
Bir index
içinde
ayrılmış(reserve)
sayfaların sayısı
Reserved
lndex
tarafından
kullanılan
sayfaların sayısı.
Used
lndex
oluşturuld
uğu
zaman
orijinal
fillfactor
değeri.
OrigFilIFactor
36. Maxirow Non-leaf index satırının en büyük boyutu. Sayısal
Keys Key sütununun açıklaması Sadece index varsa,
uygulanır.
Statversion Kaçkezistatistiklerin güncellendiği. Sayısal
Statblob Geniş binary nesnelerin istatistikleri İstatislik bilgileri tutar.
Aşağıdaki adımları uygulayarak, test edebilirsiniz;
1) Müşteriler tablosunda mevcut index'leri silelim ve clustered yapısında
cl_mad isimli mad sütunu için, yeni bir index oluşturalım.
2)Aşağıdaki kodu yazarak, sysindexes tablosundan gerekli bilgileri alalım.
37. Select id, indid, reserved, used, origfillfactor, name
From sysindexes where name=’cl_mad’
3)Çalıştırdığımızda, aşağıdaki sonuçları alırız.
GELİŞMİŞ INDEX ÖZELLİKLERİ:
Alter lndex: Yeni özelliklerden bir tanesi ALTER INDEX, Transact- SQ|-ifadesinde
bulunmaktadır. Bu yeni özellik ile bir index yenideıv düzenlenebilir, yeniden
oluşturulabilir, geçici olarak devre dışı-bırakılabilir. Böylelikle index
iyileştirmesi(defragment) için daha önce* yaptığımızı silerek yeniden oluşturma
işlemine duyulan ihtiyaç ortadan* kalkmış olur. Eskiden defragment yapmak için, index
yapısını ortadan kaldırıp(Drop lndex) ardından yeniden index oluşumu yapardık(Create
lndex). Yine bu komut ile bazı DBCC(Database Consistency CheckerU komutları
değişikliğe uğramıştır.
Online Index İşlemleri: Diğer bir özellik ise online index işlemlerine izin
vermesidir. SQL Server 2012 ile index yönetimi yaparken aynı anda başka bir
kullanıcının bu tabloyu kullanmasına izin verir. Bu eski versiyonlarında işlem sırasında
kilitleme yöntemi ile önleniyor ve o anda kullanıcı müdahale edemiyordu. Yalnız bu
işlem için ekstra disk alanına ihtiyaç olmaktadır. Çünkü veri tablosunun bir yedeği disk
üzerine alınıp değişiklik yapıldıktan sonra bu yedekten bilgilerin güncelleme prensibine
dayanır.
Paralel lndex İşlemleri: SQL Server bilgisayarında bulunan birden fazla
işlemcinin, yapılan lndex işlemlerinde paralel olarak davranması prensibine dayanan
yeni bir özelliktir. SQL Server 2012 içindeki sen/er ayarlarında bulunan max degree of
parallelism seçeneği ile otomatik olarak sağlanır. Ancak çok yoğun index işlemlerinde
38. işlemcilerin yüksek oranda kullanılması; sistemin diğer ihtiyaçlarında sıkıntı yaratabilir.
Bunun için CREATE INDEX, ALTER INDEX, DROP INDEX ifadeleri ile beraber kullanılan
MAXDOP ifadesi ile işlemci sayısına sınır getirilebilir. Eğer bunu kullanmazsak max
degree of parallelism seçeneği en yüksek işlemciye izin vermesi ile birlikte veri tabanı
motoru(Database Engine) sistem yoğunluğuna göre işlemci kısıtlamalarına gidebilir.
Kilitleme Seçenekleri: SQL Server 2012, iki kilitleme seçeneği sunmaktadır.
*** ALLOW_PAGE_LOCKS: Bu özellik açık olduğunda index işlemleri yapılırken,
kullanılan tabloda sayfa bazlı kilitleme yapar. Yani o sayfada işlem yapılırken
kullanıcının erişimine izin vermez. Kapatıldığında ise serbestlik söz konusudur.
***ALLOW_ROW_LOCKS: lndex işlemleri sırasında kullanılan tabloyu satır bazlı
kitler. Bu özellik kapatıldığında bu kitleme durumda ortadan kalkar.
Her ikiözellikte aynı anda açık olabilir.
XML lndexler: Bu xml veri tipidir.CREATE PRIMARY XML INDEX ve CREATE
XML INDEX Transact-SQL ifadeleri kullanılarak, xml veri tipi ile oluşturulmuş sütunlar
üzerinde XML lndexler oluşturulabilir.
XML lndex'leri ile beraber kullanılan XQuery işlemleri ile XML verileri üzerinde
performans gerçekten çok büyük bir oranda artar.
Ayrıca 10 performansını artırmak için kullanılan Partitioned ve Included lndex
yapısı da gelişmiş özelliklerdendir.
INDEX OLUŞTURULMASI (CREATE INDEX):
CREATE INDEX ifadesi kullanılarak bir index oluşturulur.
Aşağıdaki yazılım tüm özelliklerini göstermektedir.
CREATE [UNIQUE][CLUSTERED | NONCLUSTERED] INDEX index_ad
OH [{veri tabanı_ad.[şema_ad]. | şema_ad.}]
{tablo_veya_view_ad){sütun [ASC | DESC][,...n]) [INCLUDE
{sütun_ad[,...n])] NTH(<ilişkisel_index_seçeneklerk>[,...ri)]
[ON{partition_şema_ad{süur_ad[,...n)
| filegroup_ad | DEFAULT}]
<ilişkisel_index_seçenekleri>::=
{PAD_INDEX = {ON | OFF}
| F1LLFACTOR = fillfactor
| SORTJNJTEMPDB = {ON | OFF}
| IGNORE_DUP_KEY = {ON | OFF}
I STATISTICS_NQ_RECOMPUTE = {ON | OFF}
| DROP_EXISTING = {ON | OFF}
| ONLİNE = {ON | OFF}
i ALLOW_ROW_LOCKS = {ON | OFF}
] ALLOW_PAGE_LOCKS = {ON | OFF}
j MAXDOP = işlemci sayısı}
39. Ayrıca Management Studio içindeki Object Explorer altındaki her bir tablonun
veya View'ın altında bulunan lndexes klasörü üzerinde sağ tuşa basılarak; seçilen New
lndex seçeneği sonucu açılan iletişim kutusunda tüm bu ayarlar grafiksel olarak
yapılmaktadır.
.
Not: Ayrıca PADJNDEX, SORT_IN_TEMPdb, ONLINE ve IGNORE_DUP_KEY seçenekleri
Maintenance Plan Wizard ile ayarlanabilir.
40. Aşağıdaki yazılım ONLINE yapısını aktif hale getirmek için kullanılır. Bu yazılımda
hem sayfa, hem de sütun kilitlemesinin her ikisi de aktif hale gelir.
CREATEINDEX ad_index
ONdeneme(ad)
VVITH(ONLINE=ON)
Eğer sadece sütun kilitlemesi yapacak isek aşağıdaki gibi yazmamız gerekir.
CREATEINDEX ad_index
ONdeneme(ad)
WITH (ALLOW_ROWJ_OCKS = ON,ALLOW_PAGE_LOCKS=OFF)
Not: Tablo içindeki xml, text, ntext, image, varchar(max), nvarchar(max),
varbinary(max) veya filestream veri tipine sahipsütunlar için ONLINE özelliği
kullanılamaz
Aşağıdaki yazılım ise ONLINE yapısı yanısıra maksimum iki işlemci kullanılmasını
sağlayan bir lndex oluşumuna olanak verir. [Eğer MAXDROP değeri 0 olursa o zaman
tüm işlemciler kullanılır.MAXDROPözelliği max degree of parallelisim özeliğine
göre baskındır.
41. CREATE INDEX ad_index
ONdeneme(ad)
WITH(ONLINE=ON,MAXDROP=2)
Aşağıdaki yazılım ise include index yapısına örnek teşkil eder. Burada adres temel
index yapısı oluştururken, leaf node adresdetay1 ve adresdetay2 sütunlarını da ilaveten
içerir.
Bu yapı kapsamlı sorgulamalar için tercih edilir. Ancak index içindeki çift ayıtların
korunmasında ek yük getirecektir.
CREATEINDEX adres_index
ONdeneme(adres)
INCLUDE (adresdetayl ,adresdetay2)
XML INDEXyapısı için CREATE [PRIMARY] XML INDEX ifadesi kullanılır.
Temel özellikleri aşağıdaki gibidir.
*** XML INDEX oluşturmadan önce tabloda mutlaka Clustered lndex olmalıdır.
*** Bir xml veritipine sahip sütun üzerinde PRIMARY XML INDEX
oluşturulduktan sonra, istenirse ikinci xml index yapısı oluşturulabilir.
*** Bir xml index yapısında ONLINE seçeneği kullanılamaz.
CREATE [PRIMARY] XML INDEX index_ad ON
[{veritaban_ad.[şema_ad. şema_ad.}]tablo_ad (xml_sûtun_ad)
[ USING XML INDEX xml_index_ad
[FOR{VALUE|PATH}]
[NTH(<xmnndex_seçenekeleri>[,...n])]
CREATE PRIMARY XML INDEX yas_index
ON deneme(yas)
INDEX DEĞİŞİKLİĞİ (ALTER INDEX):
ALTER INDEX ifadesi ile var olan bir index seçenekleri üzerinde değişiklik
yapılabilir. Ayrıca yine var olan bir index üzerinde yeniden yapılandırma, geçici olarak
devre dışı bırakma gibi işlemler de yapılabilir.
Tüm kullanım parametrelerini verecek olursak;
ALTER INDEX {index__ad | ALL}
ON [{veritaban_ad.[şema_ad. | şema_ad.}]
{tablo_ veya_ vie w_ad
{ REBUİLD ^NJH(<rebuildJndex__seçeneklerh>l...n])]
43. SORTJN_TEMPDB, STATISTICS_NORECOMPUTE veIGNORE_DUP_KEY gibi
seçenekler için kullanılır.
Aşağıdaki örnekte FILLFACTOR özelliğinin kullanılması gösterilmektedir.
ALTER INDEX ad_index
ON deneme
REBUİLD WITH (FILLFACTOR=80)
Bir clustered index yeniden yapılandırırken; tüm nonclustered indexler
otomatik olarak yeniden yapılandırılmaz. Ancak ALL ifadesi ile bu işlem
gerçekleştirilebilir.
ALTER INDEX ALL
ON deneme
REBUİLD WITH(FILLFACTOR=80)
ONLINE ve MAXDROP seçenekleri ile birarada kullanılabilir.
Not: ALTER INDEX ifadesi, repartition için yeni bir sütun eklemek veya
var olan bir sütunu silmek için kullanılamaz. Bunun için CREATE INDEX
ifadesinin DROP_EXISTING seçeneği kullanılması gerekir.
REORGANIZE:
lndex uygulanmış satırlarda çok fazla sayıda tarama, sorgulama yapmak
istediğimizde performansı arttırmak için kullanabileceğimiz bir seçenektir. Ekstra bir
disk alanına ihtiyaç duymaz.
LOB_COMPACTIONifadesi kullanılarak çok geniş bilgi depolayan alanlarda
performans arttırımı sağlanır. Bu veri tipleri; image, text, ntext, varchar(max),
nvarchar(max) ve varbinary(max).
ALTER İNDEX ad_index
ON deneme
REORGANİZE WİTH (LOB_COMPACTİON=ON)
DISABLE:
lndex yapısını devre dışı bırakmak için kullanılan seçenektir. Index devre dışı
kalırken eğer bünyesinde primary key-foreign key ilişkisi varsa bu yapılar da devre dışı
kalır.
Veri tabanı motoru, devre dışı kalmış bir index yapısını korumaz. Yeniden aktif
hale getirmek için ALTER INDEX ...REBUILD veya CREATE INDEX ... WITH
DROP_EXISTING ifadelerinin kullanılması gerekir. Devre dışı kalmış constraintler
mutlaka ALTER TABLE ifadesi ile aktif hale getirilmelidir.
Eğer bir tabloya ait bir clustered index devre dışı bırakılmış ise, bu tablo OFFLINE
olarak işaretlenir. Bunun sonucunda tablo ile ilgili herhangi bir değişiklik engellenir.
Aynı zamanda SELECT sorgulamalarında uygun performans sağlamaz Taa ki tekrar aktif
44. hale getirilene dek.
ALTER INDEX ad index
ON deneme
DISABLE
Tekrar aktif hale getirmek için;
ALTER INDEX ad index
ON deneme
REBUILD
SET:
İndex seçeneklerini değiştirmek için kullanılır. Bu seçenekler;
ALLOW_ROW_LOCKS,ALLOW_PAGE_LOCKS, |GNORE_DUP_KEY, ve
STATISTICS_NORECOMPUTE olabilir.
Örneğin: LOB_COMPACTION ifadesinin kullanılabilmesi için mutlaka
ALLOW_PAGE_LOCKS seçeneğinin ON olması gerekir.
ALTER 1NDEXad_index
ON deneme
SET(ALLOW_PAGE_LOCKS= ON)
INDEX SİLİNMESİ (DROP INDEX):
lndexleri silmek için DROP INDEX ifadesi kullanılır. XML index yapıları da dahil
olmak üzere, tüm index yapıları için bu ifade kullanılır.
Tüm kullanım şekillerini verecek olursak;
DROP INDEX index ad
ON [şema_ad.]{tablo_veya_view_adl [
WITH (<drop_index_seçenekleri>l,...ri) ]
<drop index seçenekleri
{ ONLINE = {ON | OFF) |
MAXDOP = işlemci sayısı i
MOVETO { partition şema |
filegroup_ad DEFAULT}
_ad{sûtu
n_ac{,.
Ayrıca Management Studio kısmından da yapılabilir;
DROPINDEX:
lndex silmesi için kullanılır. Kullanımı SQL Server 2005'den itibaren değişmiştir.
DROP 1MDEX ad_index ON
deneme
45. MAXDROP ve ONLINE ifadelerine sadece clustered index yapısında destek verir.
Aşağıdaki ifade ile index silinirken, aynı zamanda işlemci sayısını belirler.
DROP iNDEX ad_index
ON denemeW1TH(ONLINE=ON,MAXDROP=3)
lndex silindikten sonra verinin özel bir yere taşınması için MOVETO ifadesi
kullanılır.
PARCALANMA(FRAGMENTATION):
SQL SERVER 2012 veri tabanı motoru ile yeni eklenen, değişen, silinen kayıtların
yol açtığı dağınıklık sonucu index üzerinde oluşan dağılma otomatik olarak toplanır.
Yani index uygun bir şekilde yeniden güncellenir.
Ancak tablo içindeki değişikliklerden sonra fiziksel olarak disk üzerinde dağılma
parçalanma olabilir. Bu da performansı düşüren unsurların başında gelir.
Parçalanmanın derecesine göre index üzerinde seçim yapabileceğimiz seçenekler;
REBUILD ve REORGANIZE olur.
REORGANIZE ile bir clustered index veya nonciustered index yapısı üzerinde
parçalanan bölgeler birleştirilir ve en uygun fillfactor ayarı index üzerine uygulanır.
Bunun sonucunda index daha küçük olur. Ayrıca bu özellik, çok fazla bilgi bulunan
sütunlarda da kullanılır.
REBUILD ise çok fazla parçalanma olduğu durumlarda daha iyi sonuç verdiği için
REORGANIZE seçeneğine tercih edilir. Bu ifade ile birçok index ayarlarını değiştirmek
mümkündür. Örneğin: REORGANIZE kısmında otomatik olarak yapılan FİLLFACTOR
değeri gibi.
REBUILD yapısının çalışmayı etkilemesi, REORGANIZE yapısına göre daha
fazladır. Bunun için hangi yöntemin seçileceği doğru olarak seçilmesi gerekir. Bunun için
eski versiyonda kullanılan DBCC SHOVVCONTIG ifadesi yerine
sys.dm_db_index_physical_stats
ifadesi kullanılır. Bunun sonucunda parçalanma miktarı tespit edilir.