Powolna zdalna instrukcja SELECT ze względu na długi „czas przetwarzania klienta”, ale szybki lokalnie

12

Po połączeniu z naszym serwerem produkcyjnym (SQL Server 2008, bardzo mocna maszyna), instrukcja SELECT zajmuje 2 sekundy , zwracając wszystkie pola (łącznie 4 MB danych).

SELECT TOP (30000) *
FROM person
WITH(NOLOCK);

Z dowolnego innego urządzenia w tej samej sieci (łączenie za pomocą uwierzytelniania SQL lub Windows) to samo zapytanie zajmuje 1 minutę i 8 sekund .

Testuję tę bardzo prostą instrukcję, aby zilustrować, że nie jest to problem z indeksowaniem ani problem związany z zapytaniami. (W tej chwili mamy problemy z wydajnością wszystkich zapytań ...)

Rzędy występują w kawałkach i nie wszystkie naraz. Natychmiast otrzymuję pierwsze rzędy, a następnie czekam ponad 1 minutę na pojawienie się partii rzędów.

Oto statystyki klienta zapytania, które jest uruchamiane ze zdalnego pola:

Query Profile Statistics
  Number of INSERT, DELETE and UPDATE statements 0
  Rows affected by INSERT, DELETE, or UPDATE statements 0
  Number of SELECT statements  2
  Rows returned by SELECT statements 30001
  Number of transactions 0

Network Statistics
  Number of server roundtrips 3
  TDS packets sent from client        3
  TDS packets received from server 1216
  Bytes sent from client         266
  Bytes received from server 4019800

Time Statistics
  Client processing time 72441 ms (72 seconds)
  Total execution time   72441 ms
  Wait time on server replies 0

Widzimy, że „Czas przetwarzania klienta” jest równy całkowitemu czasowi wykonania.

Czy ktoś wie, jakie kroki mogę podjąć, aby zdiagnozować, dlaczego transfer rzeczywistych danych zajmuje dużo czasu?

Czy istnieje parametr konfiguracyjny SQL, który ogranicza lub ogranicza szybkość przesyłania danych między komputerami?

FranticRock
źródło
Nawiasem mówiąc, próbowaliśmy skopiować plik o tym samym rozmiarze (4 MB) między serwerem DB a innym pudełkiem, co zajęło sekundę. Nie wygląda to na problem z siecią.
FranticRock
Co to jest aplikacja kliencka? SSMS na stacjach roboczych użytkowników końcowych?
Thomas Stringer
Tak Microsoft SQL Server Management Studio 10.50.1600.1. 2008 R2
FranticRock
Ten problem zaczął się, gdy przenieśliśmy centra danych, a cała maszyna została ponownie zainstalowana (wszystko łącznie z SQL). Jesteśmy z bardzo szanowanym dostawcą hostingu.
FranticRock

Odpowiedzi:

5

Twój problem jest zdecydowanie związany z siecią na podstawie twoich informacji. W związku z tym należy się tym zająć ze specjalistami ds. Sieci (nie jestem tym).

Rzeczy, które mogą pomóc:

  • Szybsze karty sieciowe (na serwerze SQL).
  • Dodanie przydzielonej / określonej karty NIC / podsieci między serwerami (serwer WWW i SQL Server).

Czy serwer WWW znajduje się w tej samej podsieci co serwer SQL?

Czy są między nimi routery / mosty itp.?

Niewiele możliwych zmian na serwerze SQL:

  • Dane wyjściowe są wysyłane przez SQL Server z zastrzeżonym MS „protokołem TDS”.
  • Domyślny rozmiar bufora TDS wynosi 4 KB. Patrz w MSDB: „Opcja rozmiaru pakietu sieciowego”
  • Kompresowanie danych (za pomocą programu SQL Server lub aplikacji zewnętrznej) - zależy od charakteru danych.

Używasz domyślnego rozmiaru: zobacz swoje statystyki: „Pakiety TDS otrzymane z serwera 1216” (4 MB / 1 K = 4KB). Tak, rozmiar bufora TDS można zmienić: patrz w Google: „Rozmiar partii protokołu TDS”

Dobra dyskusja na ten temat: „czy rozmiar pakietu sieciowego sql naprawdę determinuje ruch w obie strony?”

Jednak zmiana rozmiaru opakowania TDS będzie (nieuchronnie) mieć nieprzewidywalne skutki i powinna być stosowana w produkcji tylko w wyjątkowych przypadkach.

Pomogłaby również zmiana architektury lub wprowadzenie buforowania danych w warstwie pośredniej.

Aleksiej
źródło
8

Ten problem został już rozwiązany.

To był problem z siecią, a pudełko SQL używało karty sieciowej 100 MB / s , zamiast karty sieciowej 10 GB / s ...

Zmiana konfiguracji sieci w celu użycia właściwej karty sieciowej rozwiązała problem. Teraz uzyskujemy podobną wydajność dla wszystkich zapytań z pola Production SQL i innych pól w sieci.

Dziękuję wszystkim za pomoc.

FranticRock
źródło
Mam dokładnie ten sam problem co ty i chcę sprawdzić, z której karty sieciowej korzysta mój SQL Server. Gdzie to widzę?
Misza Zasławski
3

Przy pierwszym odczuciu wydaje się, że występują problemy z opóźnieniem sieci. Czy spojrzałeś na niektóre z liczników Network Perfmon? Mogą one dać ci pewne wskazówki na temat tego, co dzieje się z siecią.

Cytat z Jakie liczniki Perfmon powinienem monitorować i co każdy z nich oznacza?

SIEĆ IO

Aby zmierzyć sieciowe operacje we / wy, możesz użyć następujących liczników:

Interfejs sieciowy Liczba bajtów ogółem / s

Próg: trwałe wartości przekraczające 80 procent przepustowości sieci.

Znaczenie: Ten licznik wskazuje szybkość, z jaką bajty są wysyłane i odbierane przez każdą kartę sieciową. Ten licznik pomaga wiedzieć, czy ruch na karcie sieciowej jest nasycony i czy trzeba dodać inną kartę sieciową. To, jak szybko można zidentyfikować problem, zależy od rodzaju posiadanej sieci, a także od tego, czy współdzielisz przepustowość z innymi aplikacjami.

Odebrano interfejs sieciowy / bajty

Ten licznik wskazuje szybkość odbierania bajtów przez każdą kartę sieciową. Możesz obliczyć szybkość danych przychodzących jako część całkowitej przepustowości. Pomoże ci to wiedzieć, że musisz zoptymalizować przychodzące dane od klienta lub że musisz dodać inną kartę sieciową do obsługi ruchu przychodzącego.

Interfejs sieciowy Wysłane bajty / s

Ten licznik wskazuje szybkość, z jaką bajty są wysyłane przez każdą kartę sieciową. Możesz obliczyć szybkość danych przychodzących jako część całkowitej przepustowości. Pomoże ci to wiedzieć, że musisz zoptymalizować dane wysyłane do klienta lub musisz dodać inną kartę sieciową do obsługi ruchu wychodzącego.

ServerBytes Total / sec

Ta wartość nie powinna przekraczać 50 procent pojemności sieci.

Ten licznik wskazuje liczbę bajtów wysłanych i odebranych przez sieć. Wyższe wartości wskazują przepustowość sieci jako wąskie gardło. Jeśli suma Bajtów ogółem / s dla wszystkich serwerów jest w przybliżeniu równa maksymalnym szybkościom przesyłania w sieci, może być konieczne segmentowanie sieci.

Procentowy czas przerwania procesora

Ten licznik wskazuje procent czasu, jaki procesor spędza na odbiorze i obsłudze przerwań sprzętowych. Ta wartość jest pośrednim wskaźnikiem aktywności urządzeń generujących przerwania, takich jak karty sieciowe.

Interfejs sieciowy (*) Długość kolejki wyjściowej

Ten licznik sprawdza, ile wątków czeka na karcie sieciowej. Jeśli na karcie sieciowej czeka wiele wątków, najprawdopodobniej system nasyca sieciowe operacje we / wy najprawdopodobniej z powodu opóźnienia sieci lub przepustowości sieci.

Długość kolejki wyjściowej to długość kolejki pakietów wyjściowych (w pakietach). Jeśli jest to więcej niż dwa, występują opóźnienia i wąskie gardło należy znaleźć i wyeliminować, jeśli to możliwe. Ponieważ w tej implementacji żądania są kolejkowane według specyfikacji interfejsu sterownika sieciowego (NDIS), zawsze będzie to 0.

jgardner04
źródło
Po monitorowaniu tych statystyk w Perfmon zauważyłem kilka rzeczy. Łączna liczba bajtów / s nigdy nie wzrasta powyżej 700 K / s na żadnej karcie sieciowej. Nawet jeśli uruchamiam zapytanie, które żąda megabajtów danych, liczba ta wynosi około 500 000 kb / s. Nasza przepustowość wynosi 100 MBPS i nawet nie korzystamy z niej w 1%. Myślę, że gdzieś powinien być ustawiony limit, który wymusza zmniejszenie wielkości pakietów lub ogranicza szybkość przesyłania. Przerwania sprzętowe na sekundę wynoszą 700-2000. Kolejka wyjściowa jest pusta. Maksymalne użycie karty sieciowej wynosi około 4%.
FranticRock
2
Może wystąpić niedopasowanie między prędkością karty sieciowej a portem przełącznika. Czy zaangażowałeś swój zespół sieci, aby spojrzał na to od strony przełącznika?
jgardner04
2

Kilka wstępnych pytań: 1) Serwer ma klienta SQL na Prod. skonfigurowano maszynę serwerową, prawda? Więc jeśli wykonasz to samo zapytanie od klienta znajdującego się na tym samym komputerze, zostanie ono wykonane za 2 sekundy? Próbowałeś to zrobić? Czy to naprawdę 2 sekundy? 2) Wspomniałeś, że zmieniono konfigurację środowiska produkcyjnego (lub serwer produkcyjny został przeniesiony do innej sieci / całkowitej przebudowy serwera), prawda? Jaki był czas zużycia zapytania w starym środowisku produkcyjnym?

Z dowolnego innego urządzenia w tej samej sieci ... to samo zapytanie zajmuje 1 minutę i 8 sekund. 3) Mówisz, że zapytanie zwraca i jest pobierane od klienta znajdującego się na dowolnej maszynie w danej sieci (z wyjątkiem konkretnej maszyny) w około 70 sekund? Zrozumiałem poprawnie? 3.1 Nawiasem mówiąc, jaki jest czas akceptacji tego zapytania, akceptowany przez firmę? 4) Jednak określasz, że dla konkretnego komputera klienckiego, którego używasz, wyjściowy czas zapytania wynosi: Czas wykonania klienta 15:30: 48 15 minut? (i ten czas jest wyraźnie nie do przyjęcia)? Poprawny? 5) więc problem jest ograniczony do jednego komputera klienckiego? Lub na DOWOLNYM komputerze klienckim / średnim poziomie itp. (W nowym środowisku)? 6) jakie opóźnienie pokazuje ping? z komputera klienckiego na serwer? 7) Ty (lub administrator sieci) uruchomiłeś tracert na dwa sposoby (od klienta do serwera, od serwera do klienta)? Ile chmielu? Jaki jest łączny czas? 8) Czy stara sieć produkcyjna żyje? Czy możesz porównać za pomocą Ping i Traceroute - jaki był czas i przeskok między klientem a serwerem?

Z ciekawości: to jest przykład zapytania? lub dokładne sformułowanie zapytania? Zapytanie naprawdę NIE zawiera klauzuli WHERE? Zgadzam się ze mną, że jest to bardzo nietypowe .. Tabela ma indeks klastrowy czy jest stertą? Tabela zawiera w sumie ile wierszy? Stół jest mocno rozdrobniony? Z ciekawości: dlaczego warto wybrać TOP NNN? Dlaczego nie ustawić ROWCOUNT NNN - a następnie WYBIERZ *? To zapytanie jest wydawane ile razy klient dziennie? 1? 100? 1 MLN? Podstawowe dane są statyczne lub dynamiczne i ulegają znacznej zmianie? Ile (0,01 procent dziennie? 1 procent dziennie? 10 procent dziennie?) Dane wyjściowe zapytania są przetwarzane programowo? (nie przez użytkownika?) Dlaczego nie jest buforowany / nie jest przechowywany w warstwie pośredniej? dzięki, Aleksiej

Aleksiej
źródło
Dziękuję bardzo za informacje. Moje odpowiedzi poniżej. 1. Prawidłowo. Narzędzia klienckie również są zainstalowane na prod, a to samo zapytanie, o którym wspomniałem, zajmuje 2 sekundy, aby zwrócić wszystkie 30 000 rekordów (w sumie 4 MB). Nawiasem mówiąc, zapytanie, którego użyłem, jest tylko przykładem. To nie jest prawdziwe zapytanie biznesowe. To tylko sposób na uzyskanie 4 MB danych z tabeli. Obecnie mamy problem z wydajnością odczytu kilku megabajtów danych z dowolnej tabeli z dowolnym zapytaniem.
FranticRock
2. Czas zużycia był bliski, jeśli nie taki sam jak w przypadku tego samego zapytania uruchomionego lokalnie z pola PROD. (IE 2 sekundy) 3. Zgadza się 1 min 8 sekund to czas wykonania. Czas ten różni się w zależności od komputera klienckiego. Z naszej maszyny programistycznej (zlokalizowanej znacznie dalej niż maszyna sceniczna) uruchomiłem to zapytanie 8 razy z rzędu, a czas wahał się od 11 sekund do 22 sekund. (średnio 18 sekund)
FranticRock
z naszego dev box tracert Prod_IP_Address 1 53 ms 52 ms 53 ms SQL2008 Z maszyny scenicznej czas jest konsekwentnie ponad 1 minutę. tracert Prod_IP_Address tracert: 1 1 ms <1 ms <1 ms SQL2008 Z produkcyjnego serwera WWW: czas wykonania wynosi 53 sekundy. tracert: 1 1 ms <1 ms <1 ms SQL2008
FranticRock
4. Górna kolumna „Czas wykonania klienta” to tylko czas lokalny komputera (IE: 15:30:00). 5. Problem występuje na każdym komputerze uderzającym w produkcyjny serwer DB, w tym na naszym produkcyjnym serwerze internetowym. 6. Opóźnienie ping wynosi <1 MS od pola stage do prod SQL. 7. Proszę zobaczyć powyżej. 8. Niestety stara sieć już nie istnieje.
FranticRock
To naprawdę interesujące, że chociaż DEV pinguje 53 MS, uruchomienie zapytania zajmuje tylko 11-22 sekund. Chociaż etap pinguje 1 MS, powrót danych trwa dłużej niż 1 minutę. Dev jest również znacznie dalej geograficznie. A scena jest tuż obok pudełka z produktami, a jednak trwa znacznie dłużej.
FranticRock