Kamu Kurumunda Release Sonrası %100 CPU: View Optimizasyonu ve Filtered Index ile Yarım Günde %5’e
Bir kamu kurumunun vatandaş başvurularını yöneten uygulamasında yeni sürüm yayına alındıktan sonra veritabanı sunucusunun CPU kullanımı %100'e kilitlendi. Aryasoft, sorunu yeni takip ekranının sorguladığı tek bir view'a kadar izledi; view'u yeniden yazıp açık kayıtlara özel bir filtered index ekleyerek CPU kullanımını yarım günlük bir çalışmayla %5'e indirdi. Sürüm geri alınmadı, sunucu yeniden başlatılmadı.
mesai saatlerinde ortalama
logical reads, takip ekranı sorgusu
takip ekranının veri sorgusu
veritabanında aktif istek sayısı
Müşteri Hakkında
-
SektörKamu
-
OrtamVatandaş başvurularını yöneten, mesai saatlerinde yoğun kullanılan iş uygulaması
-
Müşteri TürüKamu kurumu (kurum adı gizli tutulmuştur)
-
Veri Tabanı TeknolojisiMicrosoft SQL Server, kurum içi (on-premises) altyapı
-
İş ÖnceliğiHizmet sürekliliğiKesintisiz vatandaş hizmetiKontrollü değişiklik
Arka Plan
Yeni Sürüm Yayına Alındı, CPU %100'e Kilitlendi
Kurum; vatandaş başvurularının kaydedildiği, birimler arasında yönlendirildiği ve sonuçlandırıldığı bir iş uygulamasını SQL Server üzerinde çalıştırıyordu. Uygulamanın yeni sürümüyle birlikte, personelin açık başvuruları birim ve durum bazında izleyebildiği yeni bir takip ekranı devreye alındı.
Sürüm mesai başlangıcından önce yayına alındı. Personel sisteme girmeye başladıkça veritabanı sunucusunun CPU kullanımı hızla yükseldi ve kısa sürede %100'e kilitlendi. Ekranlar yavaşladı, uygulama tarafında zaman aşımları başladı ve başvuru işlemleri aksamaya başladı.
Sürümü geri almak, yeni ekranla birlikte gelen diğer düzeltmeleri de geri almak anlamına geliyordu. Kurum, hizmeti durdurmadan ve sürümü geri almadan kalıcı bir çözüm istedi.
Zorluklar
Açık Başvuruları Döndüren View Tüm Tabloyu Tarıyordu
Yeni takip ekranı, her açılışta ve belirli aralıklarla yenilenirken aşağıdaki view'u sorguluyordu. Başvuru tablosundaki on milyonlarca satırın yalnızca küçük bir kısmı açıktı; ancak view'daki koşullar SQL Server'ın bu küçük kümeye doğrudan ulaşmasını engelliyordu.
AS
SELECT b.BasvuruId, b.BirimId, b.BasvuruTarihi,
dbo.fn_DurumAdi(b.DurumId) AS DurumAdi,
br.BirimAdi
FROM dbo.Basvuru AS b
INNER JOIN dbo.Birim AS br
ON br.BirimId = b.BirimId
WHERE ISNULL(b.KapanisTarihi, '19000101') = '19000101';
-- ISNULL ile sarılmış kolon: index kullanılamıyor, tablo baştan sona taranıyor
-- Skaler fonksiyon taranan her satır için ayrı ayrı çalışıyor
-- Açık kayıtlar için destekleyici index yok
Mesai Saatinde %100 CPU
Yeni ekranı açan her personel aynı ağır sorguyu tetikledi. Eş zamanlı istek sayısı arttıkça CPU kullanımı %100'e kilitlendi ve diğer tüm işlemler beklemeye başladı.
SARGable Olmayan Koşul
KapanisTarihi kolonunun ISNULL içine alınması, SQL Server'ın index ile doğrudan açık kayıtlara ulaşmasını engelledi; her çalıştırmada tablonun tamamı tarandı.
Satır Satır Çalışan Skaler Fonksiyon
Durum adını döndüren skaler fonksiyon taranan her satır için ayrı ayrı çağrıldı. Bu, CPU maliyetini katladı ve planı verimsizleştirdi.
Geri Alma Seçeneği Yoktu
Sürüm başka kritik düzeltmeleri de içerdiği için geri alınamıyordu. Çözümün hizmet durmadan, canlı ortamda uygulanması gerekiyordu.
Çözüm
View'un Yeniden Yazılması ve Açık Kayıtlara Özel Filtered Index
Aryasoft, uygulama kodunda değişiklik gerektirmeden, yalnızca veritabanı nesnelerini düzenleyerek sorunu yarım günlük bir çalışmayla çözdü.
Canlı İş Yükü Analizi
sp_WhoIsActive, Query Store ve DMV'ler ile CPU tüketen sorgular sıralandı. Toplam CPU süresinin büyük bölümünün yeni takip ekranının çağırdığı tek bir sorgu ailesinden geldiği görüldü.
Execution Plan İncelemesi
Plan, başvuru tablosunda her çalıştırmada tam tarama yapıldığını ve skaler fonksiyonun taranan her satır için çağrıldığını gösterdi. Açık başvurular tablonun yalnızca küçük bir yüzdesiydi.
View'un Yeniden Yazılması
Verinin 1900-01-01 tarihini içermediği doğrulandıktan sonra ISNULL koşulu, anlamı aynı kalacak şekilde KapanisTarihi IS NULL olarak değiştirildi. Skaler fonksiyonun yerini durum tablosuyla bir join aldı. View'un döndürdüğü kolonlar değişmediği için uygulamada değişiklik gerekmedi.
Açık Kayıtlara Özel Filtered Index
Yalnızca kapanmamış başvuruları içeren ve ekranın filtrelediği kolonlara göre tasarlanan bir filtered index oluşturuldu. Index tablonun tamamı yerine yalnızca açık kayıtları içerdiği için küçük kaldı ve bakım maliyeti düşük oldu.
Test ve Kontrollü Uygulama
Değişiklikler önce test ortamında sonuç kümesi karşılaştırmasıyla doğrulandı, ardından canlı ortamda online olarak uygulandı. CPU, sorgu süreleri ve bekleme istatistikleri değişiklik sonrasında izlendi.
Aryasoft Çözümü
CREATE OR ALTER VIEW dbo.vw_AcikBasvurular
AS
SELECT b.BasvuruId, b.BirimId, b.BasvuruTarihi,
d.DurumAdi, br.BirimAdi
FROM dbo.Basvuru AS b
INNER JOIN dbo.Durum AS d ON d.DurumId = b.DurumId
INNER JOIN dbo.Birim AS br ON br.BirimId = b.BirimId
WHERE b.KapanisTarihi IS NULL;
-- Yalnızca açık başvuruları içeren filtered index
CREATE NONCLUSTERED INDEX IX_Basvuru_Acik
ON dbo.Basvuru (BirimId, DurumId, BasvuruTarihi)
WHERE KapanisTarihi IS NULL
WITH (ONLINE = ON);
Sonuçlar ve Kazanımlar
CPU Kullanımı %100'den %5'e İndi
Takip ekranının sorgusu tüm tabloyu taramak yerine yalnızca açık başvuruları içeren küçük index'ten okumaya başladı. Uygulama aynı gün normale döndü.
CPU Baskısı Kalktı
Mesai saatlerinde ortalama CPU kullanımı %100'den %5 civarına indi ve sunucuda yeni iş yükleri için yeniden kapasite açıldı.
Milisaniyeler Seviyesinde Yanıt
Takip ekranının veri sorgusu saniyeler süren çalışmadan milisaniyeler seviyesine indi; zaman aşımları sona erdi.
Sürüm Geri Alınmadı
Çözüm view ve index düzeyinde kaldı. Uygulama kodu değişmedi, sürüm geri alınmadı, sunucu yeniden başlatılmadı.
Kesintisiz Kamu Hizmeti
Başvuru işlemleri çalışma boyunca devam etti; analizden canlıya alıma kadar tüm çalışma yarım günde tamamlandı.
Temel Çıkarım
Release'ler Fonksiyonel Testin Yanında Performans Testinden de Geçmeli
Yeni bir ekranın sorguladığı tek bir view, üretim verisi ve gerçek kullanıcı sayısıyla karşılaştığında tüm sunucuyu kilitleyebilir; test verisi küçük olduğunda bu sorun görünmez. Yeni sürümlerdeki view ve sorguların execution plan'larını üretim hacmine yakın veriyle incelemek, ISNULL gibi SARGable olmayan koşulları ve satır satır çalışan skaler fonksiyonları yayından önce yakalar. Filtered index'ler, tablonun küçük bir alt kümesini sürekli sorgulayan ekranlar için en verimli araçlardan biridir. Tasarım ayrıntıları için SQL Server index rehberimize göz atabilirsiniz.
Yeni Bir Sürüm SQL Server'ınızı Zorluyor mu?
Aryasoft; yüksek maliyetli sorguları, execution plan'ları, view'ları ve index'leri canlı iş yükü üzerinde analiz eder, uygulamayı durdurmadan kalıcı çözümler uygular.