SQL Server’da Index Forcing ile Query Optimizer’a Müdahale Etmek

SQL Server Query Optimizer (Sorgu Optimizasyonu), bir sorguyu çalıştırmak için en düşük maliyetli yolu seçmek üzere tasarlanmış son derece gelişmiş bir mekanizmadır. Ancak bazen, istatistiklerin güncel olmaması veya “Parameter Sniffing” gibi nedenlerle Optimizer en verimli index’i seçemeyebilir. Bu gibi durumlarda, SQL Server’ı belirli bir index’i kullanmaya zorlamaya Index Forcing denir.

Index Forcing, bir sorgu içerisinde Query Hint (Sorgu İpucu) kullanarak SQL Server’a “Kendi planını bırak ve benim belirttiğim index üzerinden veriyi getir” talimatını vermektir. Normal şartlarda SQL Server, tablodaki verileri tararken (Scan) mi yoksa index üzerinden mi (Seek) gideceğine maliyet tabanlı karar verir.

Aşağıdaki örnek bir select cümlesi ile index’in nasıl forcing edildiğini görmüş oluruz.

select * from Person.Address WITH (INDEX=IX_Address_AddressLine,NOLOCK)
where AddressLine2='Unit E'

Index zorlamak her zaman “iyi bir fikir” değildir, ancak aşağıdaki durumlarda hayat kurtarıcı olabilir:

  • İstatistikler güncel değilse ve manuel güncelleme o an yapılamıyorsa.
  • Optimizer, index kullanmanın maliyetini (I/O) yanlış hesaplayıp “Parallel Scan” yapmaya karar verirse.
  • Daha önce hızlı çalışan bir sorgunun, yeni bir execution plan ile aniden yavaşlaması durumunda geçici çözüm olarak.

Bu yöntem güçlü olduğu kadar tehlikelidir. “Kaş yapayım derken göz çıkarmamak” için şu noktaları göz önünde bulundurmalısınız:

  1. Eğer zorladığınız index’i ileride silerseniz veya adını değiştirirseniz, o index’i kullanan tüm sorgular hata verecek ve çalışmayacaktır.
  2. Tablodaki veri dağılımı değiştiğinde, zorladığınız index artık en hızlı yol olmayabilir. Optimizer normalde buna adapte olurken, Index Hint kullandığınızda sistem “kör” kalır.
  3. Yanlış bir index kullanımı, sorgunun çok daha fazla sayfa okumasına ve veritabanında gereksiz lock’lamalara yol açabilir.

Altın Kural: Index Forcing her zaman en son çare olmalıdır. Önce istatistikleri güncellemeyi (UPDATE STATISTICS) veya index’i yeniden oluşturmayı (REBUILD) denemelisiniz.

SQL Server 2016 ve sonrası sürümlerde, kodun içine müdahale edip Index Hint yazmak yerine Query Store üzerinden “Plan Forcing” yapılması önerilir. Bu sayede kodunuzu değiştirmeden, SQL Server yönetim arayüzü üzerinden daha iyi performans gösteren eski bir planı sisteme dayatabilirsiniz.

Bu makale ile partition maintenance ve index forcing konularını birleştirerek veritabanı performansı üzerinde ne gibi etkiler olabileceğine değinmiş olduk. Başka makalede görüşmek dileğiyle.

“Lokmân, “Sevgili oğlum” (dedi), “Yaptığın iş bir hardal tanesi ağırlığında bile olsa, bir kayanın içinde saklansa veya göklerde yahut yerin dibinde bulunsa yine de Allah onu açığa çıkarır. Kuşkusuz Allah her şeyi bütün gizlilikleriyle bilir, O her şeyden haberdardır.”Lokman-16

Author: Yunus YÜCEL

Bir yanıt yazın

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