Neden “Geçici iş yükleri için optimize et” şeklinde SQL Server seçeneğini kullanmayayım?


49

Bu gibi Kimberly Tripp tarafından SQL Server planı önbelleğe alma ile ilgili bazı harika makaleler okudum: http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

Neden "geçici iş yükleri için optimize et" seçeneği bile mevcut? Bu her zaman açık olmamalı mı? Geliştiriciler geçici SQL kullanıyor olsun veya olmasın, neden bu seçeneği (SQL 2008+) destekleyen her durumda etkin hale getirmediniz, böylece önbellek kabarıklığı azaltıyor?

Yanıtlar:


45

SQL Server geliştirme ekibi en az sürpriz prensibiyle çalışır; bu nedenle, SQL Server genellikle önceki sürümlerde olduğu gibi davranışı sürdürme konusunda engellenmiş olan yeni özelliklere sahiptir.

Evet, geçici iş yükleri için optimize etmek, plan önbellek boşluğunu azaltmada harika - ama her zaman önce test edin!

[Düzenleme: Kalen Delaney ilginç bir anekdotu anlatırken, Microsoft mühendis arkadaşlarından birine bunu etkinleştirmenin uygun olmayacağı durumlar olup olmadığını sordu. Söylemek için birkaç gün sonra geri geldi - çok sayıda farklı sorgusu olan bir uygulama hayal edin ve her sorgu toplamda iki kez çalışır. O zaman uygunsuz olabilir. Bunun gibi pek fazla uygulama olmadığını söylemek yeterli!

[Düzenleme: Sorgularınızın çoğunluğu bir kereden fazla yürütüldüyse (tam olarak iki kez değil); muhtemelen uygunsuz olurdu. Genel kural, veritabanında çok sayıda tek kullanımlık geçici sorgular varsa, bunu çevirmek olacaktır; Ancak, hala böyle uygulamalar yok.]


9
+1 yeni özellikler varsayılan olarak çok, çok nadiren açılır. Gerçekten herhangi iyi nedenler düşünemiyorum değil kötü durumda adresinden tüm sorgular tek kullanımlık olup yine önbelleğe yarar olmaz - bu spesifik özelliği açmak.
Aaron Bertrand

1
Bu, sağduyuya dayalı "güvenli" bir cevaptır ve soruyu ele almaz. Soru soran, bu özelliği açmayacak NOT durumunun ne zaman daha iyi olacağını özellikle bilmek istiyor.
MikeTeeVee

2
MikeTeeVee - güvenli bir cevap olabilir, ancak bu gerçekten bunu etkinleştirmemek için bir neden düşünemediğim özelliklerden biri. Harika olduğu için neden varsayılan olarak kapalı olduğunu açıklamak istedim!
Peter Schofield

21

Aşağıda, " geçici iş yükleri için optimize etmenin AÇIK / KAPALI duruma getirilmesinin " yararlı olup olmayacağına karar vermenize yardımcı olacak küçük bir kod verilmiştir . Bunu normalde kurum içi ve müşteri sunucuları için sağlık kontrolümüzün bir parçası olarak kontrol ederiz.

Etkinleştirmek için en güvenli seçenektir ve Brad tarafından iyi tarif edilmektedir burada Glenn Berry tarafından burada .

--- for 2008 and up .. Optimize ad-hoc for workload 
IF EXISTS (
        -- this is for 2008 and up
        SELECT 1
        FROM sys.configurations
        WHERE NAME = 'optimize for ad hoc workloads'
        )
BEGIN
    DECLARE @AdHocSizeInMB DECIMAL(14, 2)
        ,@TotalSizeInMB DECIMAL(14, 2)
        ,@ObjType NVARCHAR(34)

    SELECT @AdHocSizeInMB = SUM(CAST((
                    CASE 
                        WHEN usecounts = 1
                            AND LOWER(objtype) = 'adhoc'
                            THEN size_in_bytes
                        ELSE 0
                        END
                    ) AS DECIMAL(14, 2))) / 1048576
        ,@TotalSizeInMB = SUM(CAST(size_in_bytes AS DECIMAL(14, 2))) / 1048576
    FROM sys.dm_exec_cached_plans

    SELECT 'SQL Server Configuration' AS GROUP_TYPE
        ,' Total cache plan size (MB): ' + cast(@TotalSizeInMB AS VARCHAR(max)) + '. Current memory occupied by adhoc plans only used once (MB):' + cast(@AdHocSizeInMB AS VARCHAR(max)) + '.  Percentage of total cache plan occupied by adhoc plans only used once :' + cast(CAST((@AdHocSizeInMB / @TotalSizeInMB) * 100 AS DECIMAL(14, 2)) AS VARCHAR(max)) + '%' + ' ' AS COMMENTS
        ,' ' + CASE 
            WHEN @AdHocSizeInMB > 200
                OR ((@AdHocSizeInMB / @TotalSizeInMB) * 100) > 25 -- 200MB or > 25%
                THEN 'Switch on Optimize for ad hoc workloads as it will make a significant difference. Ref: http://sqlserverperformance.idera.com/memory/optimize-ad-hoc-workloads-option-sql-server-2008/. http://www.sqlskills.com/blogs/kimberly/post/procedure-cache-and-optimizing-for-adhoc-workloads.aspx'
            ELSE 'Setting Optimize for ad hoc workloads will make little difference !!'
            END + ' ' AS RECOMMENDATIONS
END

7

Yalnızca 5 farklı sorguya hizmet veren bir üretim sunucusunu, ancak saniyede birkaç bin kişiyi düşünün. Siz Microsoft SQL Server geliştirme ekibisiniz. Plan önbelleğe alma ile keman olacaksın. En büyük ve en kritik müşterilerinizden bazılarının (örneğin, Microsoft'un dahili SAP uygulaması) aynı kampüste çalıştığını ve yaptığınız kafeteryayı kullandığını biliyorsanız, bu davranışı varsayılan olarak etkinleştirir misiniz?


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Paul Beyaz

7

" Geçici İş Yükleri İçin En İyileştir " seçeneğini etkinleştirdiğinizde , 2. kez çalışan geçici sorguların, 1 kadar yavaş olmasına neden olacaksınız, çünkü bir Uygulama Planı Derleyip aynı Verileri çekeceksiniz ( önbellek olmadan) ilk 2 kez.
Bu büyük bir sorun olmayabilir, ancak sorguları test ederken fark edeceksiniz.
Peki, şimdi bu seçenek açılmadan ve 1-Off Ad-Hoc sorgularıyla dolu bir önbellek olmadan ne olacak ?

Önbellek Yönetimi Algoritması:

Bu Optimizasyon özelliği tanıtıldıkça, önbellek yönetimi algoritması da güncellendi.
Kimberly Tripp'in makalesi, Kalen Delaney'in bu algoritma değişikliği hakkındaki yayınına da atıfta bulunuyor .
En iyisini açıklıyor:

Değişiklik aslında SQL Server'ın bellek baskısı olduğunu algıladığı bir plan önbellek boyutunu hesaplar ve planları önbellekten kaldırmaya başlar. Kaldırılacak planlar, yeniden kullanılmamış ucuz planlardır ve bu iyi bir şeydir.

Bu, sinir bozucu bir zamanlayıcı planlarının, kaynakları boşaltmanız gerektiğinde ilk gidecek olan anlamına geleceği anlamına gelir.

Öyleyse şimdi soru şöyle:

    “ Neden SQL Server gerektiğinde kullanılmayan planları kaldırmayı önemsiyorsa 'Neden Hoc İş Yükleri için Optimize Et' İHTİYACIM VAR? ” Buna

cevabım, eğer düzenli olarak s-ton dinamik olmayan sql üreten oodles parametresi olmayan reklamlarınız varsa -hoc sorgular, sonra bu özelliği açmak için mükemmel mantıklı.
Maksimum önbellek bellek alanını kullandıktan sonra önbellek planını / verilerin kaldırılmasını zorlayacak şekilde sistem kaynaklarının zorlanmasından kaçınmak istersiniz.

Bunu ne zaman açmam gerektiğini nasıl bilebilirim?

İşte size şu anda kaç tane Hoc Planını önbelleğe aldığınızı ve ne kadar disk alanı tükettiklerini göstermek için yazdığım bir sorgu (sonuçlar gün boyunca değişecek - bu nedenle yoğun bir yük sırasında test edin):

--Great query for making the argument to use "Optimize for Ad Hoc Workloads":
SELECT S.CacheType, S.Avg_Use, S.Avg_Multi_Use,
       S.Total_Plan_3orMore_Use, S.Total_Plan_2_Use, S.Total_Plan_1_Use, S.Total_Plan,
       CAST( (S.Total_Plan_1_Use * 1.0 / S.Total_Plan) as Decimal(18,2) )[Pct_Plan_1_Use],
       S.Total_MB_1_Use,   S.Total_MB,
       CAST( (S.Total_MB_1_Use   * 1.0 / S.Total_MB  ) as Decimal(18,2) )[Pct_MB_1_Use]
  FROM
  (
    SELECT CP.objtype[CacheType],
           COUNT(*)[Total_Plan],
           SUM(CASE WHEN CP.usecounts > 2 THEN 1 ELSE 0 END)[Total_Plan_3orMore_Use],
           SUM(CASE WHEN CP.usecounts = 2 THEN 1 ELSE 0 END)[Total_Plan_2_Use],
           SUM(CASE WHEN CP.usecounts = 1 THEN 1 ELSE 0 END)[Total_Plan_1_Use],
           CAST((SUM(CP.size_in_bytes * 1.0) / 1024 / 1024) as Decimal(12,2) )[Total_MB],
           CAST((SUM(CASE WHEN CP.usecounts = 1 THEN (CP.size_in_bytes * 1.0) ELSE 0 END)
                      / 1024 / 1024) as Decimal(18,2) )[Total_MB_1_Use],
           CAST(AVG(CP.usecounts * 1.0) as Decimal(12,2))[Avg_Use],
           CAST(AVG(CASE WHEN CP.usecounts > 1 THEN (CP.usecounts * 1.0)
                         ELSE NULL END) as Decimal(12,2))[Avg_Multi_Use]
      FROM sys.dm_exec_cached_plans as CP
     GROUP BY CP.objtype
  ) AS S
 ORDER BY S.CacheType

Sonuçlar: görüntü tanımını buraya girin

Bunu açmak için " X MB’niz olduğunda " veya " Ad Hoc’unuzun% X’i Tek Kullanımlıksa " demeyeceğim .
Sprocs, Tetikleyiciler, Görünümler veya Parametrelenmiş / Hazırlanmış SQL'i etkilemez - yalnızca Geçici sorguları.
Benim kişisel tavsiyem, Prod Ortamınızda sadece açmak, ancak Dev Ortamınızda kapalı bırakmayı düşünmektir.
Bunu söylemek sadece bir dakika çalıştırmak için ya da daha fazla süren bir sorgu optimize eğer, o zaman o önbelleğe sahip ile gidecek kadar hızlı görebilirsiniz önce bunu 3 kez çalıştırmak istemiyorum, çünkü Dev için - her tek seferde en iyi optimizasyon tasarımını bulmak için düzenlersiniz.
İşiniz bütün gün bunu yapmayı gerektirmiyorsa, o zaman delirip DBA'dan her yerden açmasını isteyin.


0

“Neden kullanmamalıyım…” Bazı performans araştırmaları sırasında, plan kullanımını önbellekten gerçek zamanlı olarak çıkarmak, kaynak kullanımını gözlemlemek çok yararlı olabilir. "Anlık iş yükleri için optimize et", ani saplama planları, önbellek sorgulanırken bir plan döndürmeyeceğinden bunu bozabilir. Böyle bir durumda, sorgu ve plan başka türlü tanımlanamıyorsa, soruşturma amacıyla ayar kapatılabilir ve tekrar açılabilir. Ayardaki bir değişikliğin, bu noktadan itibaren derlenen sorguları etkilediğine dikkat edin. Ayrıca, bir 'sunucu' özelliğini ne zaman değiştirirseniz, değişikliğin plan önbelleğini temizleyip temizlemediğini doğrulamak için aynı sürümde prod olmayan bir örneği kontrol edin. Ben şahsen buna şaşırmaktan nefret ediyorum. (Örneğin, sunucu düzeyinde maxdop değiştirmek genellikle plan önbelleği temizler,

"Derlenmiş plan saplama onunla ilişkili bir yürütme planına sahip değildir ve plan tanıtıcısı için sorgulama bir XML Showplan döndürmez." http://technet.microsoft.com/en-us/library/cc645587.aspx

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.