İÇİNDEKİLER
- •Aynı sorgu bazen hızlı bazen yavaş mı?
- •Parameter Sniffing Nedir ve Neden Hata Değildir
- •Nasıl Tanınır
- •Tanı İş Akışı
- •Adım 1: Ortalama ile en kötü çalıştırma arasında büyük fark olan planları bulun
- •Adım 2: Birden fazla planı ve çok farklı süreleri olan sorguları arayın
- •Adım 3: Derleme değeri ile çalışma zamanı değerini karşılaştırın
- •Adım 4: Eski istatistikleri eleyin
- •Adım 5: Sürümünüzün ve ayarlarınızın otomatik olarak ne yaptığını kontrol edin
- •Belirti → Kanıt → Çözüm Matrisi
- •Çözüm Merdiveni: En Az Müdahaleciden En Çok Müdahaleciye
- •1. Girdileri düzeltin: istatistikler ve index’ler (istatistikleri değiştirir)
- •2. PSP’nin yapmasına izin verin (SQL Server 2022+, Azure SQL)
- •3. Kodda ifade düzeyi hint’ler (modülü değiştirir)
- •4. Query Store hint’leri (SQL Server 2022+, Azure SQL; kod değişikliği yok)
- •5. Query Store’da bilinen iyi planı zorlayın (davranışı değiştirir)
- •6. Tek bir nesneyi yeniden derleyin; son çare ve yalnızca gerekirse (cache’lenmiş planları değiştirir)
- •Karar Ağacı
- •Resmi Davranış, Aryasoft Saha Notları ve Önerimiz
- •Sık Yapılan Hatalar
- •Sık Sorulan Sorular
- •Aryasoft Sorgu İncelemelerinde Nasıl Çalışır?
- •Kaynaklar
- •Aynı sorgunun neden hız değiştirdiğini tahmin etmeyi bırakın
Parameter sniffing, SQL Server’ın planı ilk çalıştırmadaki parametre değerleriyle derleyip sonra bu planı yeniden kullanması demektir. Normaldir ve genellikle yardımcı olur. Veri dağılımı dengesizse ve tek bir cache’lenmiş plan bazı değerler için kötüyse zarar verir. Parametre değerine göre plan ve süreleri karşılaştırarak teşhis edin; çözümü plan cache’i temizleyerek değil, istatistik, recompile hint’i, Query Store hint’i veya plan zorlama ile yapın.
Bu rehber, parameter sniffing’i yavaş sorguların diğer nedenlerinden ayıran kanıtları, belirti-çözüm matrisini, karar ağacını ve teşhis ile her çözüm için çalıştırılabilir T-SQL’i gösterir. Her çözüm, sunucuda değişiklik yapıp yapmadığı ve gerektirdiği sürümle etiketlenmiştir.
Aynı sorgu bazen hızlı bazen yavaş mı?
Aryasoft, planları, istatistikleri ve Query Store geçmişini birlikte inceleyerek sorgunuzun parametre kaynaklı mı yoksa başka bir nedenle mi yavaşladığını belirler ve en düşük riskli düzeltmeyi önerir.
Son doğrulama: 19 Ekim 2026. Microsoft Learn dokümantasyonu (Parameter Sensitive Plan optimization, Query Store hint’leri, plan zorlama, Query Store ve plan cache görünümleri, database scoped configuration) ile karşılaştırıldı. T-SQL örnekleri SQL Server 2025 (build 17.0.4055.5) üzerinde test edilmiştir. Davranışı değiştiren betikler etiketlidir; üretimden önce bir test instance’ında deneyin.
Parameter Sniffing Nedir ve Neden Hata Değildir
Microsoft, parameter sniffing’i SQL Server’ın derleme veya yeniden derleme sırasında mevcut parametre değerlerini “koklayıp” Query Optimizer’a iletmesi ve böylece potansiyel olarak daha verimli planlar üretilmesi süreci olarak tanımlar. Saklı yordamlar, sp_executesql ile gönderilen sorgular ve prepared sorgular için gerçekleşir.
Sorun, düzgün olmayan veri dağılımlarında ortaya çıkar. On siparişi olan bir müşteri için ideal olan plan, on milyon siparişi olan müşteri için kötü bir seçim olabilir ve tersi de geçerlidir. Microsoft bunu, parametreli bir sorgu için tek bir cache’lenmiş planın gelebilecek tüm parametre değerleri için en uygun olmadığı durum olarak tanımlar.
Nasıl Tanınır
- Aynı saklı yordam veya parametreli sorgu bazı parametre değerlerinde hızlı, bazılarında çok yavaştır.
- Kod değişmeden, yeniden başlatma, istatistik güncellemesi, index değişikliği veya plan düşmesinden sonra performans değişir.
- Yavaş ifadeyi sorgu penceresinde sabit değerlerle çalıştırmak hızlıdır, uygulama çağrısı ise yavaştır.
- Bir planın maksimum süresi veya mantıksal okumaları ortalamasından çok yüksektir (aşağıdaki 1. betik) veya tek bir sorgunun çok farklı sürelere sahip birden fazla planı vardır (2. betik).
Bunların hiçbiri tek başına sniffing’i kanıtlamaz. Eski istatistikler, eksik index ve bloklama da aynı hikayeyi üretebilir; bu yüzden aşağıdaki iş akışı bunları sırayla kontrol eder. Yavaşlık değere bağlı değil de sürekliyse, bunun yerine wait istatistikleri iş akışımızla başlayın.
Tanı İş Akışı
Aşağıdaki 1 ile 5 arası betikler yalnızca sistem ve katalog görünümlerinden okur. Çözüm bölümünde davranışı değiştiren betikler DEĞİŞTİRİR etiketiyle işaretlenmiştir. Query Store görünümlerini okumak için Query Store açık olmalıdır; plan cache görünümlerini okumak için VIEW SERVER STATE veya platformunuzdaki eşdeğeri gerekir.
Adım 1: Ortalama ile en kötü çalıştırma arasında büyük fark olan planları bulun
sys.dm_exec_query_stats, cache’teki plan başına minimum, maksimum ve toplam geçen süreyi (mikrosaniye cinsinden) ve mantıksal okumaları tutar. Yalnızca hâlâ cache’te olan planları kapsar. İfade metni sys.dm_exec_sql_text görünümünden gelir.
-- 1. Salt okunur. En yavaş çalıştırması ortalamasının çok üzerinde olan önbellekteki planlar.
-- 10 katsayısı başlangıç eşiğidir, kural değildir.
SELECT TOP (20)
qs.query_hash,
qs.execution_count,
qs.creation_time,
qs.last_execution_time,
qs.total_elapsed_time / qs.execution_count / 1000 AS avg_elapsed_ms,
qs.min_elapsed_time / 1000 AS min_elapsed_ms,
qs.max_elapsed_time / 1000 AS max_elapsed_ms,
qs.total_logical_reads / qs.execution_count AS avg_logical_reads,
qs.min_logical_reads,
qs.max_logical_reads,
DB_NAME(st.dbid) AS database_name,
OBJECT_NAME(st.objectid, st.dbid) AS object_name,
SUBSTRING(st.text,
(qs.statement_start_offset / 2) + 1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(st.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset) / 2) + 1) AS statement_text
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
WHERE qs.execution_count >= 5
AND qs.max_elapsed_time > 10 * (qs.total_elapsed_time / qs.execution_count)
ORDER BY qs.max_elapsed_time DESC;
Adım 2: Birden fazla planı ve çok farklı süreleri olan sorguları arayın
Query Store planları ve çalışma istatistiklerini zaman içinde kaydeder; bu yüzden cache’ten çoktan çıkmış planları da gösterir. avg_duration mikrosaniye cinsindendir ve execution_type = 0 normal, başarıyla biten çalıştırma anlamına gelir.
-- 2. Salt okunur. Son 7 günde birden fazla planı olan sorgular, en iyi ve en kötü plan arasındaki
-- farka göre sıralı. Query Store gerektirir.
WITH plan_stats AS (
SELECT p.query_id,
p.plan_id,
SUM(rs.count_executions) AS executions,
SUM(rs.avg_duration * rs.count_executions)
/ NULLIF(SUM(rs.count_executions), 0) / 1000.0 AS avg_duration_ms,
SUM(rs.avg_logical_io_reads * rs.count_executions)
/ NULLIF(SUM(rs.count_executions), 0) AS avg_logical_reads
FROM sys.query_store_plan AS p
JOIN sys.query_store_runtime_stats AS rs ON rs.plan_id = p.plan_id
JOIN sys.query_store_runtime_stats_interval AS i
ON i.runtime_stats_interval_id = rs.runtime_stats_interval_id
WHERE rs.execution_type = 0
AND i.start_time >= DATEADD(DAY, -7, SYSDATETIMEOFFSET())
GROUP BY p.query_id, p.plan_id
)
SELECT TOP (20)
ps.query_id,
COUNT(*) AS plan_count,
SUM(ps.executions) AS total_executions,
MIN(ps.avg_duration_ms) AS best_plan_avg_ms,
MAX(ps.avg_duration_ms) AS worst_plan_avg_ms,
LEFT(qt.query_sql_text, 200) AS query_text_start
FROM plan_stats AS ps
JOIN sys.query_store_query AS q ON q.query_id = ps.query_id
JOIN sys.query_store_query_text AS qt ON qt.query_text_id = q.query_text_id
GROUP BY ps.query_id, LEFT(qt.query_sql_text, 200)
HAVING COUNT(*) > 1
ORDER BY MAX(ps.avg_duration_ms) - MIN(ps.avg_duration_ms) DESC;
Bu kolonlar sys.query_store_runtime_stats, sys.query_store_plan, sys.query_store_query, sys.query_store_query_text ve sys.query_store_runtime_stats_interval görünümlerinden gelir.
Adım 3: Derleme değeri ile çalışma zamanı değerini karşılaştırın
Bu adım betikle değil, planın kendisinde yapılır. SSMS’te yavaş bir çağrının gerçek yürütme planını alın, kök operatörün özelliklerini açın ve derleme parametre değerini çalışma zamanı parametre değeriyle karşılaştırın. Plan çok seçici bir değer için derlenmiş ve şimdi çok yaygın bir değerle çalışıyorsa (veya tersi), bu parameter sniffing’in imzasıdır. Sonra aynı ifadeyi hızlı olan bir değerle çalıştırın ve iki planın operatörlerini, join türlerini ve tahmini ile gerçek satır sayılarını karşılaştırın.
Adım 4: Eski istatistikleri eleyin
Microsoft, yeni Query Store hint’lerini değerlendirmeden önce istatistik ve index bakımının tamamlanmasını önerir; çünkü bu tek başına sorunu çözebilir. Yavaş predicate’in arkasındaki tablonun istatistiklerinin yaşını ve değişiklik sayısını kontrol edin.
-- 3. Salt okunur. dbo.Orders yerine yavaş koşulun arkasındaki tabloyu yazın.
SELECT s.name AS stats_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')
ORDER BY sp.last_updated;
sys.dm_db_stats_properties, bir istatistik nesnesi için last_updated, rows, rows_sampled ve modification_counter değerlerini döndürür.
Adım 5: Sürümünüzün ve ayarlarınızın otomatik olarak ne yaptığını kontrol edin
Parameter Sensitive Plan (PSP) optimization, SQL Server 2022 (16.x) ve sonrasında, Azure SQL Database ve Azure SQL Managed Instance’ta bulunur; Microsoft, etkinleştirmek için sorgu çalışırken bağlı olduğunuz veritabanında veritabanı uyumluluk düzeyi 160’ın etkin olması gerektiğini belirtir. Scoped configuration sayfası, varsayılanın uyumluluk düzeyi 160’tan itibaren ON olduğunu söyler.
-- 4. Salt okunur. Uyumluluk düzeyi ve sniffing ile ilgili iki scoped ayar.
SELECT name, compatibility_level
FROM sys.databases
WHERE database_id = DB_ID();
-- PARAMETER_SENSITIVE_PLAN_OPTIMIZATION SQL Server 2022 öncesinde yoktur.
SELECT name, value, value_for_secondary
FROM sys.database_scoped_configurations
WHERE name IN (N'PARAMETER_SNIFFING', N'PARAMETER_SENSITIVE_PLAN_OPTIMIZATION');
-- 5. Salt okunur. Query Store bu veritabanında gerçekten veri topluyor mu?
SELECT desired_state_desc, actual_state_desc, readonly_reason
FROM sys.database_query_store_options;
-- 5b. Salt okunur. SQL Server 2022+ / Azure SQL: PSP dispatcher ve variant sorguları.
SELECT TOP (50)
qv.parent_query_id,
qv.dispatcher_plan_id,
qv.query_variant_query_id
FROM sys.query_store_query_variant AS qv
ORDER BY qv.parent_query_id;
sys.database_scoped_configurations görünümünde name, value ve value_for_secondary vardır; sys.database_query_store_options görünümünde desired_state_desc, actual_state_desc ve readonly_reason vardır; sys.query_store_query_variant ise variant sorguları üst sorguya ve dispatcher planına eşler.
Belirti → Kanıt → Çözüm Matrisi
| Belirti | Kanıt | Olası neden | Çözüm yönü |
|---|---|---|---|
| Aynı kod, bazı değerlerde hızlı, bazılarında çok yavaş | 1. betikte büyük maks/ortalama farkı; planda derleme ve çalışma zamanı değerleri farklı. | Temsil edici olmayan bir değer için derlenmiş plan. | Aşağıdaki çözüm merdiveninden sürüme uygun seçenek: PSP (SQL Server 2022+), Query Store hint’i, ifade düzeyinde recompile veya zorlanmış plan. |
| Sorgu istatistik güncellemesi, yeniden başlatma veya plan düşmesinden hemen sonra yavaşladı | 1. betikte yeni creation_time; 2. betikte o anda farklı bir plan görünür. |
Yeni derleme farklı bir değeri koklamış. | Kalıcı bir çözümü (hint veya zorlanmış plan) tercih edin; cache’i temizlemek yalnızca kurayı yeniden çeker. |
| Hızlı değerde bile tahmini satır sayısı gerçekten çok uzak | 3. betik eski last_updated veya yüksek modification_counter gösterir. |
Eski veya yetersiz istatistik; sniffing değil. | İstatistikleri güncelleyin, sonra hint eklemeden önce yeniden test edin. |
| Her değerde yavaş, plan sabit | 2. betik tek plan gösterir; wait’ler bloklama, I/O veya CPU’ya işaret eder. | Parameter sniffing değil. | Wait istatistikleri iş akışını, index’leri ve sorgu yeniden yazımını kullanın. |
| Uyumluluk düzeyi 160’a geçişten sonra sorgu başına çok sayıda plan, büyüyen plan cache veya Query Store | 5b betiğinde variant satırları; cache store boyutları; sorgu başına Query Store plan limiti. | PSP tasarım gereği dispatcher ve variant planları üretir. | Bir şeylerin yanlış olduğu sonucuna varmadan önce max_plans_per_query ve cache düşmesini gözden geçirin. |
Çözüm Merdiveni: En Az Müdahaleciden En Çok Müdahaleciye
En üstten başlayın ve yalnızca kanıt bir üstteki adımın yetmediğini gösterirse aşağı inin. İlk adım dışındaki her adım sunucunun davranışını değiştirir; bu yüzden üretim dışı bir kopyada test edin ve nasıl geri alınacağını yazın.
1. Girdileri düzeltin: istatistikler ve index’ler (istatistikleri değiştirir)
3. betiğin işaretlediği istatistikleri normal bakım yönteminizle güncelleyin ve bir index’in optimizer’ın tüm değerler için tek bir iyi plan seçmesini sağlayıp sağlamayacağını kontrol edin. Index rehberimize bakın. Sonrasında 1. ve 2. adımları yeniden çalıştırın.
2. PSP’nin yapmasına izin verin (SQL Server 2022+, Azure SQL)
SQL Server 2022 veya sonrasında ya da Azure SQL Database veya Managed Instance üzerindeyseniz, uyumluluk düzeyi 160 tek bir parametreli ifade için birden fazla aktif plan tutan PSP optimization’ı açar. Query Store hint’lerine başvurmadan önce Microsoft’un önerdiği gibi uygulamayı önce daha yeni uyumluluk düzeyinde test edin. Microsoft’un belgelediği sınırlar: PSP şu anda yalnızca eşitlik (equality) predicate’leriyle çalışır, en riskli en fazla üç predicate’i değerlendirir ve parameter sniffing kapalıyken veya RECOMPILE hint’i varken devre dışıdır.
SQL Server 2025 ve veritabanı uyumluluk düzeyi 170’ten itibaren Microsoft dört PSP iyileştirmesi listeler: DML ifadeleri için destek (DELETE, INSERT, MERGE, UPDATE), tempdb için genişletilmiş destek, aynı tabloda birden fazla uygun predicate olduğunda ek değerlendirme ve query_with_parameter_sensitivity extended event’inde değişiklikler.
3. Kodda ifade düzeyi hint’ler (modülü değiştirir)
Kod size aitse, hassas ifade üzerindeki bir hint en küçük kapsamdır. OPTION (RECOMPILE) o ifadeyi her çalıştırmada gerçek değer için derler; her çağrıda derleme süresi maliyeti vardır, bu yüzden çok sık çalışan sorgularda kaçının. OPTION (OPTIMIZE FOR UNKNOWN), koklanan değer yerine ortalama yoğunluğa dayalı plan ister; kararlı olabilir ama tek bir değer için nadiren en iyisidir.
-- 6. MODÜLÜ DEĞİŞTİRİR. Bir kopyada test edin. Örnek yordam; isimler yer tutucudur.
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); -- veya: OPTION (OPTIMIZE FOR UNKNOWN)
END;
4. Query Store hint’leri (SQL Server 2022+, Azure SQL; kod değişikliği yok)
Query Store hint’leri, uygulama kodunu değiştirmeden sorgu hint’leri uygular. Kalıcıdır, yeniden başlatma ve failover’lara dayanır ve koda gömülü ifade düzeyi hint’lerin ve mevcut plan guide hint’lerinin üzerine yazar. Query Store gerektirir ve SQL Server 2022 (16.x) ve sonrası, Azure SQL Database ve Azure SQL Managed Instance için belgelenmiştir. Hint ayarlamak için veritabanında ALTER yetkisi gerekir. Hint uygulanamıyorsa sorgu engellenmez ve son hata sys.query_store_query_hints içinde görülür.
Microsoft, desteklenen hint’ler arasında RECOMPILE, OPTIMIZE FOR UNKNOWN, MAXDOP ve USE HINT listeler; OPTIMIZE FOR (@var = val) ve USE PLAN desteklenmeyenler arasındadır; ikincisi için Query Store plan zorlamasını kullanın.
-- 7a. Salt okunur. query_id değerini bulun. Prosedür içindeki bir ifadenin metni prosedür adını içermez, bu yüzden object_id ile eşleştirin.
SELECT q.query_id, qt.query_sql_text
FROM sys.query_store_query_text AS qt
JOIN sys.query_store_query AS q ON q.query_text_id = qt.query_text_id
WHERE q.object_id = OBJECT_ID(N'dbo.GetOrdersByCustomer');
-- 7b. DAVRANIŞI DEĞİŞTİRİR (SQL Server 2022+ / Azure SQL). 42 yerine kendi query_id değerinizi yazın.
EXEC sys.sp_query_store_set_hints
@query_id = 42,
@query_hints = N'OPTION (RECOMPILE)';
-- 7c. Salt okunur. Hintin ve varsa hata nedenini inceleyin.
SELECT query_hint_id, query_id, query_hint_text,
last_query_hint_failure_reason_desc, source_desc
FROM sys.query_store_query_hints
WHERE query_id = 42;
-- 7d. GERİ ALMA.
EXEC sys.sp_query_store_clear_hints @query_id = 42;
Bir PSP üst sorgusuna Query Store hint’i konursa variant’lar bunu devralır; üst sorguya RECOMPILE hint’i eklenirse PSP RECOMPILE olan sorgularda çalışmadığı için sistem PSP olmayan planlar üretir.
5. Query Store’da bilinen iyi planı zorlayın (davranışı değiştirir)
sp_query_store_force_plan, SQL Server’ın sorguyu her gördüğünde seçilen planı kullanmaya çalışmasını sağlar; zorlama başarısız olursa bir extended event tetiklenir ve optimizer normal şekilde derler. Veritabanında ALTER yetkisi gerektirir ve ortaya çıkan plan zorlanan planla aynı veya benzerdir; bu yüzden performans farklı olabilir ve nadiren belirgin şekilde kötü olabilir. Microsoft’un Query Store rehberi ayrıca zorlamanın garanti olmadığını, plandaki nesneler değiştirildiğinde veya silindiğinde tipik olarak başarısız olmaya başladığını belirtir; bu yüzden zorlanan planları düzenli kontrol edin.
-- 8a. DAVRANIŞI DEĞİŞTİRİR. Id değerlerini 2. betikte bulduğunuz iyi planla değiştirin.
EXEC sys.sp_query_store_force_plan @query_id = 42, @plan_id = 7;
-- 8b. Salt okunur. Zorlama çalışıyor mu? Hataları düzenli kontrol edin.
SELECT plan_id, query_id, is_forced_plan, force_failure_count,
last_force_failure_reason_desc
FROM sys.query_store_plan
WHERE query_id = 42;
-- 8c. GERİ ALMA.
EXEC sys.sp_query_store_unforce_plan @query_id = 42, @plan_id = 7;
Zorlanan planı aynı iki id ile sp_query_store_unforce_plan kullanarak geri alın. PSP kullanan bir veritabanında Microsoft, aynı yordamların dispatcher veya variant planları üzerinde çalıştığını, bir variant’ı zorlamanın üst dispatcher’ı zorlamadığını ve bir dispatcher’ı zorlamanın yalnızca o dispatcher’ın variant’larını uygun kıldığını belgeler.
6. Tek bir nesneyi yeniden derleyin; son çare ve yalnızca gerekirse (cache’lenmiş planları değiştirir)
sp_recompile, tek bir yordam, trigger veya fonksiyonun mevcut planını cache’ten düşürür ve bir sonraki çalıştırmada yeni plan oluşturulur. Nesne bir tablo veya view ise, ona başvuran tüm modüller yeniden derleme için işaretlenir; bu geniş kapsamlı olabilir.
-- 9. Tek bir modülün ÖNBELLEKTEKİ PLANLARINI DEĞİŞTİRİR. Geçici rahatlama, çözüm değil: sonraki
-- çalıştırma ilk gelen değeri koklar. Tablo değil, yordam adı yazın.
EXEC sp_recompile N'dbo.GetOrdersByCustomer';
Kritik
Planları sunucu genelinde temizlemek, örneğin plan handle vermeden DBCC FREEPROCCACHE, tüm sorguların aynı anda yeniden derlenmesine ve CPU artışına neden olabilir; ayrıca yalnızca bir sonraki koklanacak değeri değiştirir. Microsoft, bir veritabanının procedure cache’ini ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE ile temizlemenin o veritabanındaki tüm sorguların yeniden derlenmesi anlamına geldiğini belirtir. Gerekirse tek bir plan için, sakin bir pencerede ve geri alma planıyla yapın.
Uyarı
PARAMETER_SNIFFING = OFF ayarı trace flag 4136’ya eşdeğerdir ve Microsoft, sniffing bu flag, scoped configuration veya DISABLE_PARAMETER_SNIFFING ile kapatıldığında ilgili iş yükleri için PSP optimization’ın da devre dışı kaldığını belgeler. Tek sorguya kapsamlı bir hint tercih edin.
Karar Ağacı
Soruları sırayla izleyin ve eşleşen ilk dalda durun.
- Sorgu her parametre değerinde yavaş mı? Evet: büyük olasılıkla sniffing değil. Wait’leri, bloklamayı, index’leri ve sorgu yapısını kontrol edin. Hayır: devam edin.
- İstatistikler eski veya çok değişmiş mi (3. betik)? Evet: başka bir şey değiştirmeden önce güncelleyin ve tekrar test edin.
- SQL Server 2022+ veya Azure SQL üzerinde misiniz ve uyumluluk düzeyi 160 veya üstü mü? 4. betiği kontrol edin.
- Evet ve PSP predicate türünüze uyuyor (eşitlik): hint eklemeden önce PSP’nin zaten çözüp çözmediğini test edin. Variant’lar için 5b betiğine bakın.
- Hayır: PSP kullanılamaz. Sonraki soruyla devam edin.
- Kodu değiştirebiliyor musunuz? Evet: hassas ifadede ifade düzeyinde
OPTION (RECOMPILE)veyaOPTIMIZE FOR UNKNOWN(6. betik). Hayır veya üretici uygulaması: SQL Server 2022+ veya Azure SQL’de Query Store hint’i kullanın (7. betik). - Tüm önemli değerler için yeterince iyi tek bir plan var mı ve Query Store açık mı? Evet: zorlayın (8. betik), hataları izleyin ve şema veya veri hacmi değişikliklerinden sonra yeniden değerlendirmek için hatırlatıcı koyun.
- Hâlâ çözülmedi mi? Kalıcı çözüm üzerinde çalışırken geçici rahatlama olarak tek yordam üzerinde
sp_recompilekullanın. Tüm cache’i temizlemeyin.
Resmi Davranış, Aryasoft Saha Notları ve Önerimiz
| Konu | Resmi davranış (Microsoft) | Aryasoft saha notu | Önerimiz |
|---|---|---|---|
| PSP kullanılabilirliği | SQL Server 2022, Azure SQL Database ve Azure SQL Managed Instance için geçerlidir; veritabanı uyumluluk düzeyi 160 ile etkinleşir. | Uyumluluk düzeyini yükseltmeden motoru yükseltmek PSP’yi kapalı bırakır; taşınan bir veritabanı eski sniffing davranışını koruyabilir. | Yükseltmeden sonra hint eklemeden önce 160 veya üstü uyumluluk düzeyinde test edin. |
| PSP kapsamı | Yalnızca eşitlik predicate’leriyle çalışır, sorgu başına en fazla üç predicate; içgörü için Query Store entegrasyonu önerilir. | Tarih aralığı gibi aralık predicate’leri, bir sorgunun yeni sürümde de hassas kalmasının yaygın nedenlerindendir. | PSP’nin her hassas sorguyu kapsadığını varsaymayın; sorgu bazında doğrulayın. |
| Query Store hint’leri | Kalıcıdır, yeniden başlatma ve failover’lara dayanır, koda gömülü hint’leri geçersiz kılar; veri hacmi ve dağılımı değiştiğinde yeniden değerlendirilmelidir. | Kimsenin hatırlamadığı bir hint yarının gizemi olur. | Her hint’i query_id, gerekçe ve gözden geçirme tarihiyle kaydedin. |
| Zorlanan planlar | Zorlama garanti değildir; başvurulan nesneler değiştiğinde başarısız olabilir ve optimizer normal derleme yapar. | Geçen yılın verisi için doğru olan zorlanmış bir plan sessizce yanlış hale gelebilir. | Yalnızca force_failure_count ve çalışma süresi izlenerek zorlayın; şema veya hacim değişikliklerinden sonra gözden geçirin. |
| Cache’i temizleme | Bir veritabanının procedure cache’ini temizlemek, tüm sorgularının yeniden derlenmesi anlamına gelir. | Bir sonraki derleme daha iyi bir değeri koklayabileceği için çözüm gibi görünür, ancak yanlış değer sonra derlenince sorun geri döner. | Bunun yerine kapsamı dar, kalıcı bir çözüm kullanın. |
Sık Yapılan Hatalar
- Her sorguya
OPTION (RECOMPILE)eklemek. Her çağrıda derleme maliyeti ödersiniz ve o ifade için PSP’yi de kapatırsınız. - Sabit değerlerle test etmek. Sabit değer kendi planını alır ve sorunu gizler; uygulamanın yaptığı aynı parametreli çağrıyla test edin.
- SSMS’i SET seçeneklerine bakmadan uygulamayla karşılaştırmak. SSMS varsayılan olarak
ARITHABORT ONile bağlanır, çoğu istemci sürücüsü iseOFFkullanır. Farklı SET seçenekleri ayrı bir plan cache kaydı demektir; SSMS’te çalıştırdığınız sorgu, uygulamanın kullandığı planı değil, sizin test değerinize göre yeni derlenmiş bir planı kullanabilir. Etkisini SET seçenekleri ve ARITHABORT yazımızda anlatıyoruz. - Planı zorlayıp bırakmak. Zorlanan planları düzenli kontrol edin.
- Her yavaş sorguya sniffing demek. Eski istatistikler ve eksik index’ler dışarıdan aynı görünür.
- Ayrıca Query Store rehberimize ve performans ayarı hataları listesine bakın.
Sık Sorulan Sorular
sp_executesql sorguları ve prepared sorgular için derleme veya yeniden derleme sırasında mevcut parametre değerlerini plan oluşturmak için kullandığı süreçtir. Tek bir cache’lenmiş plan tüm değerlere uymadığında sorun olur.Aryasoft Sorgu İncelemelerinde Nasıl Çalışır?
Bir sorgu incelemesinde parametre hassasiyetini istatistik, indexleme ve çakışma sorunlarından önce kanıtla ayırır, SQL Server sürümünüzün desteklediği en dar kapsamlı çözümü seçer, nasıl geri alınacağını ve ne zaman gözden geçirileceğini belgeleriz. Daha geniş kapsam için SQL Server danışmanlığı sayfamıza bakın.
İlgili Yazılar
Kaynaklar
Bu rehberdeki teknik iddialar 19 Ekim 2026 tarihinde aşağıdaki Microsoft dokümantasyonuna karşı kontrol edildi. Gösterilen tarih dokümantasyon kaynak dosyasının “ms.date” değeridir, sayfanın değişmediğinin garantisi değildir. Sürüm desteği ve sınırlar değişir; üretimde değişiklik yapmadan önce yeniden kontrol edin.
- Query processing architecture guide: Parameter Sniffing (ms.date: 02/24/2019)
- Parameter Sensitive Plan optimization (ms.date: 02/11/2026)
- sys.dm_exec_query_stats (Transact-SQL) (ms.date: 05/30/2019)
- sys.query_store_runtime_stats (Transact-SQL) (ms.date: 05/26/2026)
- sys.query_store_plan (Transact-SQL) (ms.date: 01/23/2019)
- sys.query_store_query (Transact-SQL) (ms.date: 01/23/2019)
- sys.query_store_query_text (Transact-SQL) (ms.date: 01/23/2019)
- sys.query_store_runtime_stats_interval (Transact-SQL) (ms.date: 01/23/2019)
- sys.query_store_query_variant (Transact-SQL) (ms.date: 05/26/2026)
- sys.database_query_store_options (Transact-SQL) (ms.date: 01/23/2019)
- sys.dm_db_stats_properties (Transact-SQL) (ms.date: 12/18/2017)
- ALTER DATABASE SCOPED CONFIGURATION (Transact-SQL) (ms.date: 10/06/2026)
- sys.database_scoped_configurations (Transact-SQL) (ms.date: 05/14/2018)
- Query Store hints (ms.date: 07/25/2025)
- sys.sp_query_store_set_hints (Transact-SQL) (ms.date: 11/17/2025)
- sp_query_store_force_plan (Transact-SQL) (ms.date: 04/23/2026)
- sp_query_store_unforce_plan (Transact-SQL) (ms.date: 03/29/2016)
- sp_recompile (Transact-SQL) (ms.date: 03/16/2017)
- Best practices for monitoring workloads with Query Store (ms.date: 01/26/2026)
- sys.dm_exec_sql_text (Transact-SQL) (ms.date: 10/20/2017)
SQL Server Sorgu İncelemesi
Aynı sorgunun neden hız değiştirdiğini tahmin etmeyi bırakın
Aryasoft kıdemli DBA ekibiyle bir sorgu incelemesi planlayın. Sorunun parametre hassasiyeti, istatistik veya başka bir şey olup olmadığını bulur, size belgelenmiş ve geri alınabilir bir çözüm bırakırız.