dataiotech Labs
dbaguidedbaguideDBAdataxtoolsdataopsphere
Runbooks Library/sqlserver/#34
Runbook #34
sqlserver
PerformanceSEV3 · RISK / WARNING15-30 dakika / 15-30 minssysadmin / CONTROL SERVER / VIEW SERVER STATE

SQL Server High Compilations per Batch and Plan Cache Bloat

Separates single-use ad-hoc plans from frequently recompiled queries and addresses app parameterization and narrowly scoped server settings.

Related Metrics:M35
Related Scripts:S58S60
#plan-cache#compilations#ad-hoc#parameterization

Operational Safety & Risk Notice

This runbook contains operational intervention steps; several are write-impacting (KILL, terminate, DROP, RESIZE). Verify in a staging environment first, and apply sequentially in production with verification.

🟢 Salt Okunur (Read-Only)·🟡 Geri Alınabilir (Reversible)·🔴 Yüksek Etkili / Geri Alınamaz (High Impact)

1. Symptom & Signals

- M35 derleme/batch oranı kalıcı olarak yüksek; eşlik eden CPU baskısı olabilir.

- Plan cache'te `Adhoc` ve `usecounts = 1` planlar çok yer tutar; Query Store'da aynı SQL için çok sayıda metin/plan oluşur.

2. Business & Technical Impact

Derleme CPU'su artar, faydalı planlar cache'ten atılır; sık çalışan sorgularda kararsız gecikmeler görülür.

3. Diagnosis & Root-Cause Analysis

🟢 Read-Only1. İki perf counter'ı aynı zaman aralığında örnekleyin; `sys.dm_os_performance_counters.cntr_value` hız ismine rağmen kümülatif olabilir. Oran **iki örneğin farklarından** hesaplanır:
sql
SELECT counter_name, cntr_value
FROM sys.dm_os_performance_counters
WHERE object_name LIKE '%:SQL Statistics%'
  AND counter_name IN ('SQL Compilations/sec', 'Batch Requests/sec', 'SQL Re-Compilations/sec');

5 dakika sonra tekrar edin: `Δcompilations / NULLIF(Δbatch_requests,0)`; sıfır paydada oran üretmeyin.

🟢 Read-Only2. S58 ile plan cache toplam ve tek kullanımlık Adhoc planların boyutunu bulun:
sql
SELECT objtype, COUNT(*) AS plan_count,
       SUM(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END) AS single_use_count,
       SUM(CASE WHEN usecounts = 1 THEN CONVERT(bigint,size_in_bytes) ELSE 0 END)/1048576 AS single_use_mb
FROM sys.dm_exec_cached_plans
GROUP BY objtype
ORDER BY single_use_mb DESC;
🟢 Read-Only3. **Adhoc tek kullanım** mı, **recompile** mı, yoksa S60'ta bir sorgunun birden fazla planı mı var? Bunlar aynı teşhis değildir. Çok sayıda şablonu farklı literal'lerle üreten uygulama, SQL parametreleme eksikliğine işaret eder; recompile ise istatistik/schema değişikliği veya `OPTION (RECOMPILE)` olabilir.
🟢 Read-Only4. CPU etkisi yok ve oran workload'a özgüyse yalnızca eşik aşımı yüzünden sunucu ayarına dokunmayın.

4. Remediation & Action Plan

🟡 Reversible1. Kalıcı çözüm için uygulamada **parametreli sorgu** / `sp_executesql` kullanın. SQL injection riskini de azaltır; parametre tiplerini kolonla uyumlu tutun (örtük dönüşümden kaçının).
🟡 Reversible2. Tek kullanımlık Adhoc plan cache israfı kanıtlandıysa `optimize for ad hoc workloads` açmayı kontrollü test edin (ilk kullanımda tam plan yerine küçük stub saklanır; ayar önceden cache'te olan planları kaldırmaz):
sql
EXEC sys.sp_configure N'show advanced options', 1;
RECONFIGURE;
EXEC sys.sp_configure N'optimize for ad hoc workloads', 1;
RECONFIGURE;

Sunucu geneli değişikliktir; çalışma yükünün değişimini izleyin. Bazı planlar her çalışmada yeniden derleniyorsa bu ayar tek başına çözmez.

🟡 Reversible3. S60 Query Store'da gerçek plan regresyonu varsa parametre koklama konusunu **ayrı** ele alın. Veritabanı geneli `PARAMETERIZATION FORCED` semantiği değiştirebilir; tek metrik için körlemesine açmayın.

4. **Yapmayın:** `DBCC FREEPROCCACHE` ile tüm plan cache'i boşaltmak CPU/derleme patlaması yaratabilir; `ALTER DATABASE ... SET PARAMETERIZATION FORCED` değerini test etmeden yaymayın.

5. Verification & Health Checks

- M35 aynı pencere boyunca düşüyor; tek kullanımlık planların cache payı ve CPU basıncı azaldı.

- Query Store'da kritik sorguların çalışma süreleri ve plan kararlılığı bozulmadı.

6. Rollback & Contingency Plan

- Ayarı geri alın: `EXEC sys.sp_configure N'optimize for ad hoc workloads', 0; RECONFIGURE;`.

- Uygulama parametreleme değişikliklerini deployment geri alımıyla döndürün; ayar değişikliği cache'te önceden oluşan planları kendiliğinden temizlemez.

More SQLSERVER Runbooks