MS SQL Server’da Primary Key ve Index: Veritabanı Performansının Temelleri

Veritabanı yönetiminde en temel kavramlardan ikisi olan Primary Key ve Index yapıları, SQL Server’da hem veri bütünlüğü hem de performans açısından kritik öneme sahiptir. Bu yazıda, bu kavramları derinlemesine inceleyeceğiz.

Primary Key Nedir?

Primary Key (Birincil Anahtar), bir tablodaki her kaydı benzersiz şekilde tanımlayan sütun veya sütun kombinasyonudur. Bir tabloda sadece bir Primary Key bulunabilir ve bu alan NULL değer alamaz.

Primary Key’in Temel Özellikleri

Benzersizlik (Uniqueness): Primary Key değerleri tabloda tekrarlanamaz. Her kayıt için farklı bir değer olmalıdır.

Boş Olmama (NOT NULL): Primary Key sütunları hiçbir zaman NULL değer içeremez.

Değişmezlik: Mümkün olduğunca değişmeyen değerler Primary Key olarak seçilmelidir.

Otomatik Clustered Index: SQL Server, Primary Key tanımlandığında otomatik olarak bir Clustered Index oluşturur.

Primary Key Tanımlama

-- Tablo oluştururken Primary Key tanımlama
CREATE TABLE Kullanicilar (
    KullaniciID INT IDENTITY(1,1) PRIMARY KEY,
    KullaniciAdi NVARCHAR(50) NOT NULL,
    Email NVARCHAR(100) NOT NULL
);

-- Var olan tabloya Primary Key ekleme
ALTER TABLE Kullanicilar
ADD CONSTRAINT PK_Kullanicilar PRIMARY KEY (KullaniciID);

-- Composite Primary Key (Birleşik Birincil Anahtar)
CREATE TABLE SiparisSatiri (
    SiparisID INT,
    UrunID INT,
    Miktar INT,
    PRIMARY KEY (SiparisID, UrunID)
);

Index Nedir?

Index (Dizin), veritabanında arama işlemlerini hızlandırmak için kullanılan özel veri yapılarıdır. Kitaplardaki içindekiler tablosu gibi düşünebilirsiniz – doğrudan istediğiniz bilgiye ulaşmanızı sağlar.

Index Türleri

1. Clustered Index

  • Tablodaki verilerin fiziksel sıralanmasını belirler
  • Bir tabloda sadece bir Clustered Index olabilir
  • Primary Key otomatik olarak Clustered Index oluşturur
  • Veriler leaf seviyesinde saklanır
-- Clustered Index oluşturma
CREATE CLUSTERED INDEX IX_Kullanicilar_KullaniciAdi 
ON Kullanicilar (KullaniciAdi);

2. Non-Clustered Index

  • Verilerin fiziksel sıralamasını değiştirmez
  • Bir tabloda birden fazla Non-Clustered Index olabilir
  • Leaf seviyesinde veri değil, pointer saklar
-- Non-Clustered Index oluşturma
CREATE NONCLUSTERED INDEX IX_Kullanicilar_Email 
ON Kullanicilar (Email);

3. Unique Index

  • Benzersiz değerler için oluşturulan index
  • UNIQUE constraint otomatik olarak Unique Index oluşturur
-- Unique Index oluşturma
CREATE UNIQUE INDEX IX_Kullanicilar_Email_Unique 
ON Kullanicilar (Email);

4. Composite Index

  • Birden fazla sütunu kapsayan index
-- Composite Index oluşturma
CREATE INDEX IX_Kullanicilar_AdiSoyadi 
ON Kullanicilar (Ad, Soyad);

Covering Index ve Include Sütunları

Covering Index, sorguların ihtiyaç duyduğu tüm sütunları içeren index türüdür. INCLUDE parametresi ile performans artırılabilir.

-- Covering Index örneği
CREATE INDEX IX_Kullanicilar_Covering
ON Kullanicilar (KullaniciAdi)
INCLUDE (Email, Ad, Soyad);

Primary Key ve Index Arasındaki Farklar

ÖzellikPrimary KeyIndex
AmaçBenzersiz tanımlamaPerformans artırma
SayıTabloda sadece 1Tabloda birden fazla
NULLNULL alamazNULL alabilir
Otomatik OluşumHayırPrimary Key otomatik oluşturur
Veri BütünlüğüSağlarSağlamaz

Performans Üzerindeki Etkileri

Primary Key’in Performans Avantajları

Hızlı Arama: Primary Key üzerinden yapılan aramalar son derece hızlıdır çünkü otomatik Clustered Index kullanır.

Join Performansı: Foreign Key ilişkilerinde Primary Key kullanımı JOIN işlemlerini hızlandırır.

Replication: SQL Server replication işlemlerinde Primary Key gereklidir.

Index’in Performans Avantajları

SELECT Performansı: WHERE, ORDER BY ve JOIN clauselarında kullanılan sütunlarda index bulunması sorgu performansını dramatik şekilde artırır.

Sıralama İşlemleri: ORDER BY işlemlerinde index kullanımı sıralama maliyetini azaltır.

Gruplama İşlemleri: GROUP BY işlemlerinde uygun index kullanımı performans sağlar.

Performans Test Örneği

-- Index olmadan sorgu
SELECT * FROM Kullanicilar WHERE Email = 'test@example.com';
-- Execution Plan: Table Scan (Yavaş)

-- Index ile sorgu
CREATE INDEX IX_Kullanicilar_Email ON Kullanicilar (Email);
SELECT * FROM Kullanicilar WHERE Email = 'test@example.com';
-- Execution Plan: Index Seek (Hızlı)

Index Optimizasyon Stratejileri

Doğru Sütunları Seçmek

Sık Aranan Sütunlar: WHERE clauselarında sık kullanılan sütunlar için index oluşturun.

Selectivity: Yüksek selectivity’ye sahip sütunları (benzersiz değerlerin oranı yüksek) tercih edin.

Küçük Veri Tipleri: Index boyutunu küçük tutmak için mümkün olduğunca küçük veri tipleri kullanın.

Index Maintenance

-- Index istatistiklerini güncelleme
UPDATE STATISTICS Kullanicilar IX_Kullanicilar_Email;

-- Index fragmentasyon kontrol
SELECT 
    i.name AS IndexName,
    ps.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) ps
JOIN sys.indexes i ON ps.object_id = i.object_id 
    AND ps.index_id = i.index_id;

-- Index yeniden oluşturma
ALTER INDEX IX_Kullanicilar_Email ON Kullanicilar REBUILD;

Best Practices (En İyi Uygulamalar)

Primary Key İçin

  1. IDENTITY sütunu kullanın: Otomatik artan sayısal değerler ideal Primary Key’dir.
  2. Natural Key yerine Surrogate Key: Müşteri numarası gibi natural key yerine sistem tarafından üretilen surrogate key kullanın.
  3. Küçük veri tipi: INT yerine BIGINT sadece gerektiğinde kullanın.

Index İçin

  1. Az index, etkili index: Her sütun için index oluşturmayın, sadece gerekli olanlar için.
  2. Composite index sırası: En selective sütunu ilk sıraya koyun.
  3. Include sütunları kullanın: Covering index oluşturmak için INCLUDE parametresini kullanın.
  4. Regular maintenance: Index istatistiklerini düzenli olarak güncelleyin.

Kaçınılması Gerekenler

Over-indexing: Çok fazla index DML işlemlerini yavaşlatır.

Wide Index: Çok fazla sütun içeren index’ler performansı olumsuz etkiler.

Duplicate Index: Aynı işlevi gören birden fazla index oluşturmayın.

Monitoring ve Analiz

SQL Server, index kullanımını izlemek için çeşitli araçlar sunar:

-- Eksik index önerileri
SELECT 
    mig.index_group_handle,
    mid.index_handle,
    mid.database_id,
    mid.object_id,
    mid.equality_columns,
    mid.inequality_columns,
    mid.included_columns
FROM sys.dm_db_missing_index_groups mig
INNER JOIN sys.dm_db_missing_index_group_stats migs
    ON migs.group_handle = mig.index_group_handle
INNER JOIN sys.dm_db_missing_index_details mid
    ON mig.index_handle = mid.index_handle;

-- Index kullanım istatistikleri
SELECT 
    i.name AS IndexName,
    ius.user_seeks,
    ius.user_scans,
    ius.user_lookups,
    ius.user_updates
FROM sys.indexes i
JOIN sys.dm_db_index_usage_stats ius
    ON i.object_id = ius.object_id AND i.index_id = ius.index_id
WHERE ius.database_id = DB_ID();

Sonuç

Primary Key ve Index yapıları, modern veritabanı sistemlerinin can damarıdır. Primary Key veri bütünlüğünü sağlarken, Index yapıları sorgu performansını optimize eder. Doğru kullanıldığında bu yapılar uygulamanızın performansını önemli ölçüde artırabilir, yanlış kullanıldığında ise performans sorunlarına neden olabilir.

Başarılı bir veritabanı tasarımı için bu konseptleri derinlemesine anlamak ve uygulamak gerekir. Regular monitoring, uygun maintenance ve doğru optimizasyon stratejileri ile veritabanınızın performansını en üst seviyede tutabilirsiniz.

Unutmayın: Index oluşturmak bir sanat kadar bilim işidir. Her uygulama kendine özgü gereksinimlere sahiptir ve index stratejinizi bu gereksinimlere göre şekillendirmelisiniz.

Yorum gönder