Jakie są przyczyny braku planu w pamięci podręcznej dla procedur przechowywanych?
WITH RECOMPILE
- Dynamiczny SQL
- Zaszyfrowany kod
- Znaczące zmiany danych
- Zaktualizuj statystyki
- Co jeszcze?
Pracowałem ostatnio na 2 serwerach (SQL Server 2008 R2 i SQL Server 2012), które nie miały planów w pamięci podręcznej dla bardzo przechowywanych procedur o dużym zużyciu zasobów. Wiele, a może wszystkie instrukcje wewnątrz procedur przechowywanych również nie miały planów w pamięci podręcznej. Niektóre z procedur przechowywanych są wykonywane dość często, kilka razy na sekundę.
Brak presji pamięci. Jeden z serwerów ma znacznie więcej sprzętu niż jest to potrzebne.
Myślałem, że brakujące plany były spowodowane tymczasowym tworzeniem tabel w trakcie procedur przechowywanych, ale wydaje się, że są to stare informacje z SQL Server 2000 lub wcześniejszych. Począwszy od SQL Server 2005, rekompilacje odbywają się na poziomie instrukcji dla instrukcji po DDL. Czy to prawda we wszystkich przypadkach, czy może się to zdarzyć w nowszych wersjach?
Co jeszcze może być winowajcą za brakujące plany? Przejrzałem kilka artykułów na ten temat, ale wydaje się, że nic nie pasuje.
Optymalizacja pod kątem obciążeń adhoc jest włączona na serwerze, na który patrzę w tym tygodniu. Jedna z procedur przechowywanych jest wykonywana tylko raz dziennie. Mam kod do tego. Nie mam kodu dla tego, który wykonuje ponad 100 razy na minutę, ale mogę go zdobyć. Nie będę mógł opublikować kodu, ale mogę go opisać w związku z moim pytaniem.
Nie sądzę, aby ktokolwiek zwalniał pamięć podręczną procedur lub upuszczał czyste bufory. Ten klient używa Solarwinds DPA jako jednego ze swoich narzędzi monitorowania. DPA przechwycił jeden z planów wykonania instrukcji w przechowywanym proc, który jest wywoływany raz dziennie. To stwierdzenie ma ogromną liczbę odczytów z powodu WHERE
klauzuli niewymienialnej . Jeśli DPA przechwyciło wyciąg, to jest to plan szacunkowy i był w pamięci podręcznej planu w tym samym czasie. Po prostu nie ma go podczas rozwiązywania problemów. Poproszę, żeby zaczęli logować się sp_WhoIsActive
do stołu.
Używam sp_BlitzCache
. (Pracuję dla Brenta Ozara Unlimited) Pokaże to plan całej procedury składowanej, a także plany poszczególnych instrukcji, jeśli takie istnieją. Jeśli nie istnieją, pojawia się ostrzeżenie „Nie mogliśmy znaleźć planu dla tego zapytania. Możliwe przyczyny to dynamiczny SQL, RECOMPILE
wskazówki i kod zaszyfrowany”. To ostrzeżenie dotyczy także oświadczeń.
TF 2371 nie jest na miejscu. Patrzę na statystyki oczekiwania. Serwer jest bardzo znudzony. PLE to ponad 130 000.
Mam teraz kod dla 2 kolejnych procedur składowanych. Jeden z nich używa dynamicznego SQL, exec (@sql)
dzięki czemu wiemy, dlaczego nie ma takiego planu. Ale ten drugi, który działa ponad 100 razy na minutę, nie ma nic niezwykłego. Jedyną rzeczą, która wyróżnia się w tym, jest to, że tabele tymczasowe są tworzone w środku ponad 1000 wierszy kodu. Wywołuje również wiele procedur przechowywanych podrzędnie.
Jeśli chodzi o buforowanie planu w SQL Server 2008 , nie widzę żadnych literałów> = 8k, ale jedna z procedur przechowywanych ma komentarz na temat wstawki zbiorczej tuż przed wywołaniem innej procedury przechowywanej. Ale wkładka zbiorcza nie pojawia się w zewnętrznej procedurze przechowywanej, na którą patrzę. Część artykułu „Próg ponownej kompilacji” jest interesująca. To, co widzę w tabelach tymczasowych, to mnóstwo INSERTów (które mogą spowodować miliony wierszy), niektóre aktualizacje i usunięcia. Wiele zmian danych w tabelach tymczasowych. Miliony
źródło
Odpowiedzi:
Istnieją dwa DMF pamięci podręcznej planu:
sys.dm_exec_query_plan - zwraca plany buforowane w formacie XML, ale tylko do pewnego rozmiaru (i tylko o ile można je sformatować jako XML w SQL Server, co oznacza do 128 zagnieżdżonych poziomów).
sys.dm_exec_text_query_plan - zwraca plany buforowane w formacie tekstowym, dowolnego rozmiaru. Ale wadą jest to, że gdy plany są duże, nie można ich przekonwertować na XML wewnątrz SQL Server, a nawet TRY_CONVERT, ponieważ XML zwraca wartość null.
sp_BlitzCache uderza tylko w poprzedni DMV (ponieważ musi analizować plany zapytań jako XML, aby wykonywać wszelkiego rodzaju krojenie i krojenie w kostkę). Zrobiłem Github problem # 838, aby to poprawić, abyśmy mogli przynajmniej powiadomić użytkowników, aby sprawdzili sys.dm_exec_text_query_plan większe zapytania. Jednak nadal nie będziemy w stanie przeprowadzić na nim analizy XML.
źródło
sys.query_store_plan.query_plan
jestnvarchar(MAX)
nie XML (SQL ciekawostki).Być może musisz dostosować maksymalny rozmiar pliku XML, który SSMS może zwrócić do siatki?
źródło