Dlaczego NIE miałbym używać opcji SQL Server „optymalizuj pod kątem obciążeń ad hoc”?

49

Czytałem wspaniałe artykuły dotyczące buforowania planu SQL Server przez Kimberly Tripp, takie jak ten: http://www.sqlskills.com/blogs/kimberly/plan-cache-and-optimizing-for-adhoc-workloads/

Dlaczego istnieje nawet opcja „optymalizacji pod kątem obciążeń ad hoc”? Czy nie powinno to zawsze być włączone? Niezależnie od tego, czy programiści używają ad-hoc SQL, czy nie, dlaczego nie włączono by tej opcji w każdej instancji, która ją obsługuje (SQL 2008+), zmniejszając w ten sposób wzdęcie pamięci podręcznej?

Jakiś facet
źródło

Odpowiedzi:

45

Zespół programistów SQL Server pracuje na zasadzie najmniejszego zaskoczenia - dlatego SQL Server generalnie wyłącza nowe funkcje w celu zachowania zachowania jak w poprzednich wersjach.

Tak, optymalizacja pod kątem obciążeń adhoc jest świetna w zmniejszaniu rozdęcia pamięci podręcznej planu - ale zawsze najpierw przetestuj ją!

[Edycja: Kalen Delaney opowiada ciekawą anegdotę, że zapytała jednego ze swoich przyjaciół inżyniera Microsoft, czy będą okoliczności, w których włączenie tego byłoby niewłaściwe. Wraca kilka dni później, aby powiedzieć - wyobraź sobie aplikację, która ma wiele różnych zapytań, a każde z nich działa dokładnie dwukrotnie. Może to być nieodpowiednie. Wystarczy powiedzieć, że nie ma wielu takich aplikacji!]

[Edytuj: jeśli większość twoich zapytań jest wykonywana więcej niż jeden raz (nie dokładnie dwa razy); byłoby to prawdopodobnie niewłaściwe. Ogólną zasadą byłoby obrócenie go, jeśli w bazie danych znajduje się wiele jednorazowych zapytań adhoc; jednak wciąż nie ma wielu takich aplikacji.]

Peter Schofield
źródło
9
+1 nowe funkcje są bardzo, bardzo rzadko domyślnie włączone. Nie mogę wymyślić żadnych dobrych powodów, aby nie włączać tej konkretnej funkcji - w najgorszym przypadku wszystkie zapytania są jednorazowe i i tak nie skorzystałyby z buforowania.
Aaron Bertrand
1
To jest „bezpieczna” odpowiedź oparta na zdrowym rozsądku i nie odnosi się do pytania. Pytający chce poznać konkretnie przypadek użycia, gdy NIE włączy się tej funkcji, jest to lepsze.
MikeTeeVee
2
MikeTeeVee - może to być bezpieczna odpowiedź, ale jest to jedna z tych funkcji, w których naprawdę nie potrafię wymyślić powodu, aby jej nie włączyć. Ponieważ jest tak niesamowity, chciałem tylko wyjaśnić, dlaczego domyślnie był wyłączony!
Peter Schofield
21

Poniżej znajduje się mały kod, który pomoże ci zdecydować, czy „ optymalizacja przełączania dla obciążeń ad hoc ON / OFF” będzie korzystna czy nie. Zwykle sprawdzamy to w ramach naszej kontroli kondycji serwerów wewnętrznych i klientów.

Jest to najbezpieczniejsza opcja, aby włączyć i jest opisany dobrze Brad tutaj i Glenn Berry tutaj .

--- 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
Kin Shah
źródło
7

Pomyśl o serwerze produkcyjnym, który obsługuje tylko 5 różnych zapytań, ale kilka tysięcy z nich na sekundę. Jesteś zespołem programistów Microsoft SQL Server. Będziesz majstrować przy buforowaniu planu. Czy domyślnie włączasz to zachowanie, gdy wiesz, że niektórzy z twoich największych i najbardziej krytycznych klientów (np. Wewnętrzna implementacja SAP Microsoftu) pracują na tym samym kampusie i korzystają z tej samej kafeterii?

Stu
źródło
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Paul White
7

Włączenie opcji „ Optymalizuj pod kątem obciążeń ad hoc ” spowoduje, że zapytania ad-hoc uruchamiane 2. raz będą tak samo wolne jak 1., ponieważ będziesz kompilował plan wykonania i pobierał te same dane ( bez buforowania) te pierwsze 2 razy.
To może nie być wielka sprawa, ale zauważysz to podczas testowania zapytań.
Co się teraz stanie, jeśli ta opcja nie będzie włączona, a pamięć podręczna pełna zapytań Ad-Hoc 1-Off?

Algorytm zarządzania buforowaniem:

Po wprowadzeniu tej funkcji optymalizacji algorytm zarządzania buforowaniem również został zaktualizowany.
Artykuł Kimberly Tripp odwołuje się również do postu Kalena Delaneya na temat tej zmiany algorytmu.
Wyjaśnia to najlepiej:

Zmiana faktycznie oblicza wielkość pamięci podręcznej planu, przy której SQL Server rozpoznaje presję pamięci i rozpocznie usuwanie planów z pamięci podręcznej. Plany do usunięcia to tanie plany, które nie zostały ponownie wykorzystane, a to DOBRA RZECZ.

Oznacza to, że te nieznośne jednorazowe plany będą dostępne jako pierwsze, gdy trzeba zwolnić zasoby.

Zatem teraz pytanie brzmi:

    „ Dlaczego POTRZEBUJEMY„ Optymalizować pod kątem obciążeń ad hoc ”, gdy SQL Server zajmuje się usuwaniem nieużywanych planów, gdy jest to konieczne?

Moja odpowiedź na to pytanie, jeśli regularnie masz mnóstwo ton generujących dynamiczne sql nieparametryzowanych reklam -hoc wysyła zapytania, więc warto włączyć tę funkcję.
Chcesz uniknąć obciążania zasobów systemowych, tak że wymusza to usunięcie planu buforowanego / danych po zużyciu maksymalnej pamięci w pamięci podręcznej.

Skąd mam wiedzieć, kiedy muszę to włączyć?

Oto zapytanie, które napisałem, aby pokazać, ile aktualnie masz planów buforowanych Ad-Hoc i ile miejsca na dysku zjadają (wyniki będą się zmieniać w ciągu dnia - przetestuj je w czasie dużego obciążenia):

--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

Wyniki: wprowadź opis zdjęcia tutaj

Nie powiem „ kiedy masz X MBlubjeśli X% twoich ad hoc jest jednorazowych ”, aby to włączyć.
Nie wpływa na Sprocs, wyzwalacze, widoki ani sparametryzowany / przygotowany SQL - tylko zapytania Ad-Hoc.
Osobiście zalecam, aby włączyć się w środowisku Prod, ale rozważ pozostawienie tego w środowisku deweloperów.
Mówię to tylko dla deweloperów, ponieważ jeśli optymalizujesz zapytanie, które zajmuje minutę lub dłużej, nie chcesz uruchamiać go 3 razy, zanim zobaczysz, jak szybko pójdzie z nim w pamięci podręcznej - co jednorazowo edytujesz go, aby znaleźć najlepszy projekt optymalizacji.
Jeśli twoja praca nie polega na robieniu tego przez cały dzień, zwariuj i poproś DBA o włączenie go wszędzie.

MikeTeeVee
źródło
0

„Dlaczego NIE powinienem używać…” W trakcie niektórych badań wydajności wyciąganie planów z pamięci podręcznej planów w czasie rzeczywistym, podczas obserwowania wykorzystania zasobów może być bardzo pomocne. „Optymalizuj pod kątem obciążeń adhoc” może to zakłócić, ponieważ plany pośredniczące adhoc nie zwrócą planu podczas zapytania do pamięci podręcznej. W takim przypadku, jeśli zapytania i planu nie można zidentyfikować w inny sposób, ustawienie można wyłączyć i włączyć ponownie w celu przeprowadzenia dochodzenia. Zauważ, że zmiana w ustawieniach zapytań o efekty skompilowana od tego momentu. Ponadto za każdym razem, gdy zmieniasz właściwość „serwer”, sprawdź instancję nonprod w tej samej wersji, aby sprawdzić, czy zmiana opróżni pamięć podręczną planu. Osobiście nienawidzę być tym zaskoczonym. (Na przykład zmiana maxdop na poziomie serwera zwykle opróżnia pamięć podręczną planu,

„Do skompilowanego kodu pośredniczącego planu nie jest powiązany plan wykonania, a zapytanie o uchwyt planu nie zwróci XML Showplan.” http://technet.microsoft.com/en-us/library/cc645587.aspx

uchwyt sql
źródło