Memory module cluttered with small cards next to a neat stack, representing plan cache bloat and optimize for ad hoc workloads

Optimize for Ad Hoc Workloads: SQL Server’da Plan Cache Şişmesini Önlemek

SQL Server plan cache’teki tek kullanımlık plan şişmesini ölçmek, optimize for ad hoc workloads ayarının ne yaptığı, ne zaman açılacağı ve asıl çözümün neden parametrelendirme olduğu.

Şubat 9, 2022

SQL Server her sorgu için bir çalıştırma planı derler ve bunu plan cache’te saklar; aynı sorgu yeniden geldiğinde planı tekrar derlemek yerine cache’teki planı kullanır. Ancak birçok uygulama, değerleri sorgu metninin içine gömerek her seferinde biraz farklı bir sorgu gönderir. WHERE MusteriNo = 1001 ile WHERE MusteriNo = 1002 SQL Server için iki ayrı sorgudur. Sonuç: plan cache, bir daha hiç kullanılmayacak binlerce tek kullanımlık planla dolar ve yeniden kullanılabilir planlara, hatta buffer pool’a ayrılabilecek bellek boşa gider.

Bu yazıda plan cache şişmesini nasıl ölçeceğinizi, optimize for ad hoc workloads ayarının ne yaptığını ve sorunun asıl kaynağını nasıl çözeceğinizi anlatıyoruz.

SQL Server Performans Danışmanlığı

Belleğiniz neden tek kullanımlık planlarla dolu?

Aryasoft, plan cache'i ve uygulamanın sorgu kalıplarını inceler; parametrelendirme ve sunucu ayarlarıyla belleği verimli kullanır hale getirir.

Destek Alın

Plan Cache Şişmesini Ölçmek

Önce sorunun gerçekten var olup olmadığına bakın. Aşağıdaki sorgu, plan cache’teki planları türüne göre gruplar ve yalnızca bir kez kullanılmış planların ne kadar bellek kapladığını gösterir:

SELECT objtype,
       COUNT(*)                                             AS plan_count,
       SUM(CAST(size_in_bytes AS bigint)) / 1048576         AS total_mb,
       SUM(CASE WHEN usecounts = 1 THEN 1 ELSE 0 END)       AS single_use_plans,
       SUM(CASE WHEN usecounts = 1 THEN CAST(size_in_bytes AS bigint) ELSE 0 END) / 1048576 AS single_use_mb
FROM sys.dm_exec_cached_plans
GROUP BY objtype
ORDER BY total_mb DESC;

Adhoc satırında tek kullanımlık planlar toplam plan cache’in önemli bir bölümünü (örneğin birkaç yüz megabayt ya da gigabaytlar) oluşturuyorsa, plan cache şişmesi yaşıyorsunuz demektir.

Optimize for Ad Hoc Workloads Ne Yapar?

Bu ayar açıkken SQL Server, bir sorgu ilk kez çalıştığında planın tamamını değil, yalnızca küçük bir plan stub saklar. Aynı sorgu ikinci kez gelirse plan yeniden derlenir ve bu kez tamamı cache’e yazılır. Böylece bir daha hiç çalışmayacak sorgular, cache’te tam plan boyutu yerine yalnızca birkaç yüz baytlık yer kaplar.

EXEC sys.sp_configure N'show advanced options', 1;
RECONFIGURE;
EXEC sys.sp_configure N'optimize for ad hoc workloads', 1;
RECONFIGURE;

Ayar yeniden başlatma gerektirmez. Mevcut planları etkilemez; yalnızca bundan sonra derlenen yeni sorgular için geçerlidir. Aynı ayar SSMS’te sunucu özelliklerinin Advanced sayfasında da bulunur:

SSMS Server Properties Advanced sayfasında Optimize for Ad hoc Workloads seçeneği

Açmalı mısınız?

Çoğu sunucu için evet. Bedeli küçüktür: ikinci kez çalışan bir sorgu bir kez fazladan derlenir. Kazancı ise ad hoc sorguların yoğun olduğu sistemlerde yüzlerce megabayt bellektir. Bu yüzden ayar, birçok DBA’nın standart kurulum listesinde yer alır.

Not

Ayar açıkken bir sorgu ilk çalıştığında cache’te yalnızca stub bulunur; sys.dm_exec_query_plan bu sorgu için tam plan döndürmez. Tek seferlik bir sorgunun planını incelemek istiyorsanız, planı SSMS’te “Include Actual Execution Plan” ile ya da Query Store’dan alın.

Asıl Çözüm: Parametrelendirme

Optimize for ad hoc workloads belirtiyi hafifletir, nedeni ortadan kaldırmaz. Kalıcı çözüm, uygulamanın parametreli sorgular göndermesidir:

-- Kötü: değer sorgu metnine gömülü, her değer yeni bir plan demek
-- SELECT * FROM dbo.Siparis WHERE MusteriNo = 1001;

-- İyi: parametreli sorgu, tek plan yeniden kullanılır
EXEC sys.sp_executesql
     N'SELECT SiparisNo, Tarih, Tutar FROM dbo.Siparis WHERE MusteriNo = @MusteriNo',
     N'@MusteriNo int',
     @MusteriNo = 1001;

ORM’lerde ve uygulama kütüphanelerinde parametreli komutları kullanmak, sorguların hem plan cache’i verimli kullanmasını hem de SQL injection’a karşı korunmasını sağlar.

Uygulamayı değiştiremiyorsanız iki seçenek daha vardır:

  • Forced parameterization: ALTER DATABASE SatisDB SET PARAMETERIZATION FORCED; SQL Server, sorgulardaki sabitleri otomatik olarak parametreye çevirir. Plan cache’i ciddi şekilde rahatlatabilir; ancak bazı sorgularda parametre hassasiyeti nedeniyle daha kötü planlara yol açabilir. Önce test ortamında Query Store ile ölçün.
  • Plan guide’lar ve Query Store hint’leri: Belirli sorgu kalıpları için parametrelendirmeyi hedefli olarak açmak.

Uyarı

DBCC FREEPROCCACHE ile plan cache’i düzenli olarak temizlemek plan şişmesine çözüm değildir. Tüm sorguların yeniden derlenmesine yol açar, kısa süreli CPU artışı yaratır ve birkaç saat içinde cache yeniden dolar. Kriz anında ekipten birinin “rahatlatmak için” bu komutu çalıştırması, sorunun kaynağını bulmayı da zorlaştırır.

Kontrol Listesi

  • Plan cache’teki tek kullanımlık ad hoc planların boyutu ölçüldü.
  • optimize for ad hoc workloads açık.
  • En çok tek kullanımlık plan üreten sorgu kalıpları belirlendi ve uygulama ekibiyle paylaşıldı.
  • Uygulama değiştirilemiyorsa forced parameterization test ortamında ölçüldü.
  • FREEPROCCACHE rutin bir bakım adımı olarak kullanılmıyor.
SQL Server’ın bir sorgu ilk çalıştığında planın tamamı yerine küçük bir plan stub saklamasını sağlayan sunucu ayarıdır. Tek kullanımlık sorguların plan cache’i doldurmasını önler.
Çoğu sunucu için evet. Bedeli, ikinci kez çalışan sorguların bir kez fazladan derlenmesidir; ad hoc sorguların yoğun olduğu sistemlerde ciddi bellek kazandırır.
Hayır. sp_configure ile açıldığında hemen geçerli olur ve yeni derlenen sorgular için uygulanır.
Uygulamanın parametreli sorgular göndermesi. Değiştirilemiyorsa forced parameterization test edilerek değerlendirilebilir.

SQL Server Performans Danışmanlığı

Belleği tek kullanımlık planlara harcamayın

Aryasoft’un kıdemli DBA ekibi plan cache’i ve uygulamanın sorgu kalıplarını analiz eder; parametrelendirme, sunucu ayarları ve Query Store ile belleği verimli ve performansı kararlı hale getirir.

4.7/5