Środowisko:
Mamy dwa 32-bitowe komputery z systemem Windows Server 2003 R2 z programem SQL Server 2005. Konfiguracje sprzętowe to identyczne serwery z procesorem Xeon 5160, 4 GB pamięci RAM i 13 GB RAID0. Flagi AWE i / 3GB nie są włączone.
Serwery zostały skonfigurowane obok siebie przy użyciu wstępnie zdefiniowanej listy kontrolnej instalacji, a WSZYSTKIE zainstalowane oprogramowanie jest takie samo na obu komputerach.
Każde ustawienie instalacji serwera SQL i poziom łaty, które sprawdzamy, są identyczne. Jedną różnicą jest to, że TEMPDB ma 400 MB na szybkiej maszynie i 1,2 GB na wolnej maszynie. Jednak w obu przypadkach nie widzimy żadnej alokacji TEMPDB.
Problem:
Istnieje procedura składowana, która działa w ciągu 2 sekund z jednej, ale 15 minut z drugiej. W ciągu dodatkowych 15 minut aktywność dysku jest niewielka lub nie ma żadnych zmian w zużyciu pamięci, ale cały rdzeń procesora jest przypięty w 100%.
To zachowanie utrzymuje się, nawet gdy kopie zapasowe baz danych są przechowywane z jednej bazy danych i przywracane do drugiej.
Ponieważ jest to procedura przechowywana, monitor aktywności i profiler nie pokazują nam żadnych szczegółów na temat tego, gdzie w procedurze przechowywanej zachodzi ta wysoka aktywność procesora.
Pytanie:
Na co jeszcze powinniśmy patrzeć?
Kontynuacja:
Powolność występuje w instrukcjach FETCH NEXT dla następującej definicji kursora:
DECLARE C CURSOR FOR
SELECT X, Y
FROM dbo.A
WHERE X NOT IN (SELECT X FROM dbo.B)
AND Z <=0
...
<snip>
...
FETCH NEXT FROM C INTO @X, @Y
FETCH NEXT FROM C INTO @X, @Y
...
Każda z instrukcji FETCH - w tabeli zawierającej tylko około 1000 wierszy - wymaga około 7,25 minut. (Nie, nie wiem, dlaczego robi dwa z rzędu, muszę zapytać programistów, ale działa poprawnie na obu serwerach).
Jestem trochę podejrzliwy wobec tego „NOT IN (SELECT ...)”, ponieważ wygląda na to, że Virtual Reads jest naprawdę wysoki.
źródło
Odpowiedzi:
Używając metodologii rozwiązywania problemów z wydajnością, takich jak oczekiwania i kolejki, określ przyczynę wysokiego zużycia procesora, po zidentyfikowaniu wąskiego gardła można zalecić odpowiednie działanie.
źródło
SQL Server wybiera inny plan w drugim polu.
Przywracanie zazwyczaj usuwa problemy na podstawie statystyk, więc przyjrzałbym się różnicom między serwerami.
Najpierw niektóre zgrubne kontrole. Nie zakładaj: sprawdź
Następnie przeskocz na głęboki koniec, zgodnie z odpowiedzią Remusa.
źródło
Jeśli wszystkie inne rzeczy są sobie równe, jest prawdopodobne (zgodnie z odpowiedzią @ gbn), że na każdym serwerze generowany jest inny plan wykonania. Jako ćwiczenie akademickie byłoby interesujące zobaczyć oba plany, więc pobierz je z pamięci podręcznej planu na każdym serwerze i dodaj je do pytania, jeśli to możliwe. Następnie możemy zidentyfikować różnice w planach, które powodują tak duże zróżnicowanie wydajności.
Aby uzyskać szybką poprawkę, zapoznaj się ze wskazówką USE PLAN . Umożliwia to dołączenie dobrego planu z szybkiego serwera do procedury przechowywanej na wolnym serwerze.
Edycja: Po aktualizacji do: kursor
Jeszcze jedna odmiana zapytania, której nie widzę w innych odpowiedziach:
źródło
Humor mnie i spróbuj zastąpić:
z tym:
Nie sądzę, że powinno to objawiać się jako problem z wydajnością w części FETCH NEXT FROM twojego kodu, ale nie miałem jeszcze zastrzyku kofeiny. Wypróbuj moją sugestię i daj mi znać.
Mam nadzieję że to pomoże,
Matt
źródło
Sprawdź swoje indeksy i zaktualizuj wszystkie statystyki. Miałem bardzo podobny problem i okazało się, że statystyki na jednej maszynie były niepewne.
źródło
Dwukrotnie doświadczyłem tego samego zachowania i za każdym razem powiem ci, co to naprawiło:
1.) Dodałem podpowiedź Z RECOMPILE do procedury składowanej, ponieważ buforowany plan był okropny.
2.) Zmieniłem procedurę przechowywaną, aby używała tabel tymczasowych zamiast zmiennych tabel.
Mam nadzieję, że któraś z nich pomoże. Powodzenia.
źródło