SQL Server Query Store, istatistikler ve parametre hassasiyetiyle sorgu regresyonlarını teşhis edin. Bu uygulamalı rehber, veritabanı optimizasyonu için ölçüm, plan karşılaştırması ve kontrollü düzeltme akışı sunar.
SQL Server Eğitiminde Plan Kararlılığı ve Sorgu Regresyonları
Veritabanı performans ayarlama: önce regresyonu ölçün
Üretimde yavaşlayan bir endpoint için ilk iş indeks eklemek değil, aynı sorgunun hangi planla ne zaman bozulduğunu bulmaktır. SQL Server Query Store etkinse, son 24 saatte ortalama süre artan sorguları doğrudan sistem görünümlerinden çıkarın. avg_duration mikro saniye, avg_logical_io_reads ise 8 KB sayfa adedidir; ikisini birlikte izlemek CPU kaynaklı plan değişimini I/O kaynaklı değişimden ayırır.
DECLARE @since datetimeoffset = DATEADD(hour, -24, SYSDATETIMEOFFSET());
SELECT TOP (20)
q.query_id,
qt.query_sql_text,
p.plan_id,
rs.count_executions,
CAST(rs.avg_duration / 1000.0 AS decimal(12,2)) AS avg_ms,
CAST(rs.avg_logical_io_reads AS decimal(12,2)) AS avg_logical_reads
FROM sys.query_store_runtime_stats AS rs
JOIN sys.query_store_plan AS p ON p.plan_id = rs.plan_id
JOIN sys.query_store_query AS q ON q.query_id = p.query_id
JOIN sys.query_store_query_text AS qt ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_runtime_stats_interval AS i
ON i.runtime_stats_interval_id = rs.runtime_stats_interval_id
WHERE i.start_time >= @since
ORDER BY rs.avg_duration DESC;Karşılaştırmayı yalnız ortalama ile yapmayın: yüksek çağrı sayısında ortalama, nadir ama kritik p99 sıçramasını gizler. Application Insights, OpenTelemetry metriği veya uygulama tarafındaki histogramla endpoint gecikmesini p50/p95/p99 olarak kaydedin; SQL tarafında aynı zaman aralığında Query Store plan_id değişimini eşleyin. Örneğin bir plan değişiminden sonra ortalama logical read 120’den 84.000’e çıktıysa, sorun genellikle bellek değil seçicilik tahmini veya erişim yoludur.
SQL eğitimi için kritik konu: parametre hassasiyeti ve plan önbelleği
Parametre sniffing, prosedürün ilk derlenmesinde görülen parametre değerinin kardinalite tahmininde kullanılmasıdır. Dağılımı dengesiz bir kolonda ilk çağrı az satırlı müşteriyle yapılırsa optimizer seek + nested loops seçebilir; sonra milyon satırlı müşteri aynı önbellek planıyla geldiğinde key lookup sayısı büyür. Bu nedenle bir sql eğitimi kapsamında yalnızca "plan cache temizleme" öğretmek zararlıdır: DBCC FREEPROCCACHE semptomu geçici olarak saklar, tüm sunucudaki yeniden derlemelerle CPU dalgası da yaratabilir.
CREATE OR ALTER PROCEDURE dbo.GetOrdersByCustomer
@CustomerId int
AS
BEGIN
SET NOCOUNT ON;
SELECT o.OrderId, o.OrderDate, o.TotalAmount
FROM dbo.Orders AS o
WHERE o.CustomerId = @CustomerId
OPTION (RECOMPILE); -- yalnızca bu ifade, her çağrıda güncel değerle derlenir
END;OPTION (RECOMPILE) değişken seçiciliği gerçekten yüksek ve çağrı frekansı sınırlı olduğunda uygundur; mekanizma her yürütmede parametreyi literal gibi görüp yeni tahmin üretmesidir. Ancak saniyede yüzlerce çağrıda derleme CPU’sunu ölçmeden kullanmayın. Önce ve sonra için Extended Events’te sql_statement_completed ve query_post_execution_showplan olaylarını filtreleyin; duration, cpu_time, logical_reads ve compile sayısını aynı yük testi altında karşılaştırın. Alternatif olarak Query Store’da iyi planın zorlanması, veri dağılımı değişene kadar daha düşük operasyonel maliyetli olabilir.
Database indexleme yerine istatistik doğruluğunu doğrulayın
Database indexleme çoğu vakada erişim yolunu iyileştirir; fakat optimizer yanlış satır sayısı tahmin ediyorsa doğru indeksi bile seçmeyebilir. Özellikle birden fazla filtrede kolonlar koreleyse, tek kolon histogramları bağımsızlık varsayımıyla çarpılır ve tahmin sapar. Gerçek plan XML’inde Estimated Number of Rows ile Actual Number of Rows değerini karşılaştırın; 10 katı aşan sapma, önce istatistik veya sorgu biçimini araştırmak için somut bir eşiktir.
-- İlgili indeks/istatistiğin örnekleme oranını ve güncellenme zamanını inceleyin
SELECT s.name, sp.last_updated, sp.rows, sp.rows_sampled,
sp.modification_counter
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE s.object_id = OBJECT_ID(N'dbo.Orders');
-- Korele filtreler için hedefli çok kolonlu istatistik örneği
CREATE STATISTICS st_Orders_Status_Region
ON dbo.Orders (Status, RegionCode)
WITH FULLSCAN;FULLSCAN her tablo için varsayılan reçete değildir: terabayt ölçeğinde tarama, bakım penceresini ve I/O bütçesini tüketir. Önce modification_counter / rows oranını, son güncellenme zamanını ve tahmin hatasını kaydedin; sonra yalnız sorunlu istatistikte FULLSCAN veya uygun sample oranı deneyin. Test ortamında aynı parametre setiyle actual execution plan alın; örneğin hash join’in 6 GB memory grant istemesi 80 MB’a düşüyorsa, bu değişikliğin etkisi sadece süre değil eşzamanlı sorguların bellek kuyruğu üzerinde de ölçülebilir.
SQL Server eğitimi: Query Store ile plan zorlama ve geri alma
Query Store plan forcing, acil bir regresyonda kod dağıtımı beklemeden bilinen iyi planı seçmeye yarar. Ancak bunu kalıcı çözüm saymayın: zorlanan planın kullandığı indeks kaldırılırsa veya veri hacmi değişirse plan forcing failure oluşabilir. Önce Query Store arayüzünde ya da sys.query_store_plan üzerinden aynı query_id için geçmiş planların duration, logical reads ve execution count değerlerini karşılaştırın; ardından yalnızca ölçülebilir biçimde iyi olan planı zorlayın.
EXEC sys.sp_query_store_force_plan
@query_id = 481,
@plan_id = 913;
-- Dağıtım sonrası metrikler kötüleşirse geri alın
EXEC sys.sp_query_store_unforce_plan
@query_id = 481,
@plan_id = 913;
SELECT query_id, plan_id, is_forced_plan, force_failure_count,
last_force_failure_reason_desc
FROM sys.query_store_plan
WHERE query_id = 481;Bu sql server eğitimi akışında değişiklik kaydı tutun: query_id, plan_id, seçilen parametre örnekleri, önce/sonra p95 süre, logical read ve geri alma koşulu. Plan forcing sonrası yalnızca tek bir temsilî parametreyi test etmek yaygın hatadır; küçük, orta ve büyük sonuç kümeleri döndüren en az üç gerçek CustomerId ile yürütün. Çünkü iyi plan, küçük seçicilikte hızlı olan plan değil, kabul edilen iş yükü dağılımında kuyruklanmayı azaltan plan olmalıdır.
NoSQL eğitimiyle ortak ders: erişim desenini modelleyin
NoSQL eğitimi ile ilişkisel tasarımı karşı karşıya koymak yerine aynı soruyu sorun: okuma deseni hangi partition key veya filtre üzerinden geliyor? MongoDB’de sorgu profilini explain("executionStats") ile inceleyin; totalDocsExamined değeri dönen belge sayısından yüzlerce kat yüksekse koleksiyon taraması ya da yanlış bileşik indeks sırası vardır. SQL Server’daki actual rows/estimated rows farkı gibi, burada da docsExamined/nReturned oranı erişim modelinin doğrudan ölçüsüdür.
db.orders.find({ tenantId: "t-42", status: "OPEN" })
.sort({ createdAt: -1 })
.limit(50)
.explain("executionStats")
// Eşitlik filtreleri, ardından sıralama alanı
// db.orders.createIndex({ tenantId: 1, status: 1, createdAt: -1 })Veritabanı eğitimi programlarında taşınabilir pratik şudur: gerçek sorgu örneklerini, parametre dağılımını ve plan/istatistik çıktısını birlikte saklayın. İlişkisel tarafta Query Store; MongoDB tarafında profiler ve executionStats bunu sağlar. Bu disiplin, veritabanı optimizasyonu kararını "indeks ekleyelim" varsayımından çıkarıp taranan sayfa veya belge, bellek isteği ve kuyruk gecikmesi gibi doğrulanabilir sinyallere bağlar.
İlgili Eğitim
Sık Sorulan Sorular
SQL Server eğitiminde Query Store ile yavaş sorgu nasıl bulunur?
sys.query_store_runtime_stats, sys.query_store_plan ve sys.query_store_runtime_stats_interval görünümlerini birleştirip belirli zaman aralığında avg_duration, avg_logical_io_reads ve plan_id değerlerini sıralayın. Aynı query_id altında plan_id değişimi ile endpoint p95 artışını eşleştirin; tek bir anlık DMV çıktısına dayanmayın.
Veritabanı performans ayarlama sırasında OPTION RECOMPILE ne zaman kullanılmalı?
Parametre değerleri arasında satır sayısı çok değişiyorsa ve sorgunun çağrı hızı derleme maliyetini tolere ediyorsa kullanın. Extended Events ile cpu_time, duration, logical_reads ve derleme sıklığını önce/sonra ölçün. Yüksek frekanslı çağrılarda Query Store plan forcing veya sorgu/veri modeli düzeltmesi daha uygun olabilir.
Database indexleme mi yoksa istatistik güncellemesi mi gerektiğini nasıl anlarım?
Actual execution plan’da Actual Number of Rows ile Estimated Number of Rows farkını inceleyin. Büyük tahmin sapmasında sys.dm_db_stats_properties ile rows_sampled ve modification_counter değerlerini kontrol edin; doğru tahminde ama yüksek logical read varsa eksik ya da uygunsuz indeks hipotezini test edin. Değişikliği aynı parametre setiyle ölçmeden kalıcılaştırmayın.
NoSQL eğitimi kapsamında MongoDB sorgu maliyeti nasıl ölçülür?
find(...).explain("executionStats") çıktısındaki totalDocsExamined, totalKeysExamined ve nReturned alanlarını kaydedin. totalDocsExamined/nReturned oranı yüksekse filtre ve sort sırasına göre bileşik indeks tasarlayın; ardından aynı sorguda bu oranı ve executionTimeMillis değerini karşılaştırın.
AI / LLM Discovery
Bu makale Opendart Akademi Veritabanı eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.



