Nagły spadek wydajności programu SQL Server


13

Mam SQL Server 2005, który ostatnio stał się nieprzewidywalny, i zastanawiam się, dlaczego. Zapytania wykonywane w ciągu kilku sekund zmieniają plany i zajmują minuty (poświęcenie czasu na pełne skanowanie tabeli lub buforowanie indeksu). Teraz pierwszą i najbardziej oczywistą rzeczą jest to, że statystyki są przestarzałe, co powoduje dezorientację optymalizatora, ale jestem przekonany, że tak nie jest - po pierwsze dlatego, że podstawowe dane nie ulegają znaczącym zmianom (np. Dodanie danych jednego dnia na podstawie danych rocznych już w tabeli), a po drugie, ponieważ zarówno automatyczne tworzenie statystyk, jak i automatyczne aktualizowanie statystyk są prawdziwe. Jednak optymalizator jest coraz mylić; uruchomienie SQL w Doradcy dostrajania daje mi wiele CREATE STATISTICSinstrukcji wielokolumnowych, które wydają się go naprawiać (aż do następnego błędu w zachowaniu SQL).

Jakieś pomysły na strategię, której mogę użyć, aby podejść do tego powodując root? Czy jest jakiś powód, dla którego „normalne” statystyki nie są wystarczające?

Odpowiedzi:


8

Jeśli twoje górne oczekiwanie to SOS_SCHEDULER_YIELD, wygląda na to, że masz pewien nacisk na procesor. Ale może to wynikać z czegoś innego, na przykład z tego, że Twój projekt nie wystarcza już do Twoich zapytań. Wiem, że powiedziałeś, że dodajesz dane z jednego dnia, ale mógłbyś osiągnąć punkt zwrotny.

Jak wydawane są twoje zapytania? Czy to dynamiczny SQL? Czy korzystasz z procedur przechowywanych? Czy używasz sp_executesql? Czy to możliwe, że masz przypadek wąchania parametrów? Jak wygląda twój projekt db? Jakie są relacje PK i FK?

Czy masz przykład dobrego planu? Jeśli jesteś w stanie ustalić dobry plan, możesz użyć przewodników po planach, aby wymusić wykonanie zapytania w określony sposób.

Czy możesz podać przykład złego dobrego planu?

Na koniec, weź kopię sp_whoIsActive ( http://whoisactive.com/ ) od Adama Machanica i użyj jej, aby dowiedzieć się więcej o uruchomionych zapytaniach. Jeśli chcesz mieć możliwość przechwycenia danych wyjściowych ze sp_whoIsActive, przejdź tutaj http://www.littlekendra.com/2011/02/01/whoisactive/


Jest to aplikacja innej firmy, nie mam kontroli nad jej schematem ani SQL, co jest dość okropne, wiele sparametryzowanych zapytań (np. where col=(cast @var...)) I @varmoże być '%'. Właśnie odziedziczyłem go tydzień lub dwa lata temu i muszę działać tak długo, aż zostanie zastąpiony. Dzięki za link, dam mu wir.
Gajusz

Następnym największym oczekiwaniem SOS_SCHEDULER_YIELDbyło CXPACKETi sp_configure "max degree of parallelism", 1wydaje się, że - na razie - powaliło oba problemy na głowę. Dzięki!
Gajusz

+1 za link do sp_whoIsActive
Jeff

8

Z MSDN :

Operacje wstawiania występują w kolumnach kluczy rosnących lub malejących Statystyki dotyczące kolumn kluczy rosnących lub malejących, takich jak TOŻSAMOŚĆ lub kolumny znaczników czasu w czasie rzeczywistym, mogą wymagać częstszych aktualizacji statystyk niż w przypadku optymalizatora zapytań. Operacje wstawiania dodają nowe wartości do kolumn rosnących lub malejących Liczba dodanych wierszy może być zbyt mała, aby uruchomić aktualizację statystyk. Jeśli statystyki nie są aktualne, a zapytania wybierają spośród ostatnio dodanych wierszy, bieżące statystyki nie będą miały oszacowań liczności dla tych nowych wartości. skutkują niedokładnymi oszacowaniami liczności i powolną wydajnością zapytań.

Na przykład zapytanie, które wybiera spośród najnowszych dat zamówienia sprzedaży, będzie miało niedokładne oszacowania liczności, jeśli statystyki nie zostaną zaktualizowane w celu uwzględnienia oszacowań liczności dla ostatnich dat zamówienia sprzedaży.

Po czynnościach konserwacyjnych Należy rozważyć aktualizację statystyk po przeprowadzeniu procedur konserwacji, które zmieniają rozkład danych, takich jak obcięcie tabeli lub wykonanie masowego wstawiania dużej części wierszy. Dzięki temu można uniknąć przyszłych opóźnień w przetwarzaniu zapytań, gdy zapytania będą czekać na automatyczne aktualizacje statystyk ”.

Możesz od czasu do czasu używać „EXEC sp_updatestats” w systemie (zaplanowane jakiś czas) lub użyć funkcji STATS_DATE na wszystkich obiektach i zobaczyć, kiedy ich statystyki były ostatnio aktualizowane, a jeśli od tego czasu było za dużo, użyj UPDATE STATYSTYKA dla tego konkretnego obiektu. Z mojego doświadczenia wynika, że ​​nawet przy włączonej automatycznej statystyce wciąż jesteśmy zmuszeni aktualizować statystyki od czasu do czasu, z powodu operacji wstawiania, które nie uruchomiły automatycznej aktualizacji.

Aby dodać mój kod osobisty (używany w cotygodniowym zadaniu, które tworzy dynamiczne instrukcje aktualizacji statystyk):

select distinct
        'update statistics [' + stats.SchemaName + '].[' + stats.TableName + ']'
            + case when stats.RowCnt > 50000 then ' with sample 30 percent;'
            else 
                ';' end
        as UpdateStatement
    from (
        select
            ss.name SchemaName,
            so.name TableName,
            so.id ObjectId,
            st.name AS StatsName, 
            STATS_DATE(st.object_id, st.stats_id) AS LastStatisticsUpdateDate
            , si.RowModCtr
            , (select case si2.RowCnt when 0 then 1 else si2.RowCnt end from sysindexes si2 where si2.id = si.id and si2.indid in (0,1)) RowCnt
        from sys.stats st
            join sysindexes si on st.object_id = si.id and st.stats_id = si.indid
            join sysobjects so on so.id = si.id and so.xtype = 'U' --user table
            join sys.schemas ss on ss.schema_id = so.uid
    ) stats
    where cast(stats.RowModCtr as float)/cast(stats.RowCnt as FLOAT)*100 >= 10 --more than 10% of the rows have changed
    or ( --update statistics that were not updated for more than 3 months (and rows no > 0)
        datediff(month, stats.LastStatisticsUpdateDate, getdate()) >= 3
        and stats.RowCnt > 0
    )

Tutaj otrzymuję wszystkie obiekty, w których statystyki nie były aktualizowane przez ponad 3 miesiące lub od ostatniej aktualizacji statystyk zmieniło się ponad 10% wierszy.


Hmm, moje największe oczekiwanie to, SOS_SCHEDULER_YIELDale nie mogę teraz powiedzieć, czy to z powodu złych planów, czy też to (6-letnie, 2-procesorowe, 4G RAM) jest naprawdę przeciążone i mam przekroczył punkt krytyczny.
Gajusz

zamiast uruchamiać to zapytanie w celu wykonania instrukcji UPDATE i uruchamiać je ręcznie, można użyć kursora opartego na tej instrukcji select, aby zapętlić wyniki uruchomione przy użyciu wywołań sp_executesql - w ten sposób można uruchomić je automatycznie (na przykład jako część planu konserwacji na jedną noc (lub inny cichy okres).
David Spillett,

@David: to właśnie robię w cotygodniowej pracy :). Właśnie sformatowałem go inaczej, aby Gaius mógł zobaczyć dane wyjściowe, których używam. Początkowy skrypt był zbyt brzydki i długi. Dziękujemy za pomoc w formatowaniu! Czy możesz wysłać mnie do samouczka formatowania ... ponieważ tak naprawdę nie wiem, jak sprawić, by kod wyglądał tutaj ładnie. Dzięki!
Marian

na ekranie „edytuj odpowiedź” znajduje się link „pomoc w formatowaniu” oraz ikona po prawej stronie nad polem początkowej odpowiedzi na głównej stronie pytania, zawierająca listę składni Markdown obsługiwanej przez te witryny.
David Spillett,

3
Statystyki automatycznej aktualizacji faktycznie uruchamiają się przy 20% + 500 wierszach, a nie 10%.
mrdenny,

3

Domyślam się, że co najmniej jedna z twoich tabel jest na tyle duża, że ​​nie trafia w 20% zmian potrzebnych do oznaczenia bieżących statystyk jako nieaktualnych, tak aby uruchomiły się statystyki automatycznej aktualizacji, a mimo to dostatecznie dużo aktualizacji (lub wstawek) ), że aktualizacja statystyk bardzo by pomogła. To samo znalazłem ostatnio w określonym środowisku po aktualizacji z SQL 2000 do SQL 2008.

Oprócz innych witryn wymienionych w powyższych odpowiedziach sugeruję sprawdzenie następujących zasobów online.

1) Red-Gate oferuje wiele bezpłatnych e-booków do pobrania, w tym „SQL Server Statistics” autorstwa Holger Schmeling, gdzie znajdziesz następujący cytat:

http://www.red-gate.com/our-company/about/book-store/

„tabele zawierające więcej niż 500 wierszy co najmniej 20% danych kolumny musiały zostać zmienione, aby unieważnić jakiekolwiek połączone statystyki”

2) SQL Sentry ma bezpłatne narzędzie Eksplorator planów, które pomaga śledzić problemy w planie SQL, takie jak oszacowanie zbyt wielu lub zbyt niewielu wierszy w porównaniu z faktyczną liczbą wierszy dla danej tabeli w zapytaniu. Po prostu zapisz aktualny plan wykonania z SSMS, a następnie przejdź przez różne części planu za pomocą Eksploratora planów. Nie chodzi o to, że informacje nie są dostępne w SSMS przy użyciu graficznego planu wykonania, ale narzędzie SQL Sentry znacznie ułatwia ich zobaczenie.

http://www.sqlsentry.com/plan-explorer/sql-server-query-view.asp

3) Sprawdź datę aktualizacji statystyk dla tabel w zapytaniach, które najbardziej Cię interesują za pomocą STATS_DATE (), możesz znaleźć szybkie zapytanie, aby uzyskać najstarsze statystyki przy użyciu zapytania znalezionego w poniższej dyskusji.

http://blog.sqlauthority.com/2010/01/25/sql-server-find-statistics-update-date-update-statistics/

Mam nadzieję, że to pomoże!

Myślę, że szczególnie spodoba ci się książka Red-Gate!

-Jeff


Dzięki, przejrzę je. Jestem głównie Oracle DBA, który odziedziczył ten system (chociaż „nie jestem uprzedzony do SQL Server, z tego, co widzę od 2005 roku, jest to bardzo wydajna platforma, po prostu jej nie znam tak dobrze, jak Oracle” .
Gajusz
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.