Jak zwiększyć wydajność dziewiczych zapytań w MS SQL Server?

10

Mam witrynę sieci Web ASP.NET, która wykonuje własne buforowanie danych, a dane nie zmieniają się przez długi czas, więc nie trzeba ponownie wysyłać zapytań do programu SQL Server za pomocą tego samego zapytania. Muszę poprawić wydajność pierwszych zapytań (dziewiczych), które trafiają do tego programu SQL Server. Niektóre zapytania przetwarzają tak dużo danych, że mogą powodować użycie programu SQL Server tempdb. Nie używam zmiennych tabeli tymczasowej ani tabel tymczasowych, więc SQL Server sam decyduje się na użycie tempdb, gdy tylko zajdzie taka potrzeba.

Mój rozmiar bazy danych wynosi 16 GB, mam 32 GB fizycznej pamięci RAM na moim serwerze.

Rozumiem, że strategia buforowania MS SQL Server próbuje utrzymać dane w pamięci RAM, aby przyspieszyć wydajność podobnych zapytań, jeśli potrzebują one ponownie załadować te same dane. Oprócz tego spróbuje użyć dostępnej pamięci RAM zamiast tempdb w celu przyspieszenia wydajności bez powodowania dostępu do dysku.

Podejrzewam, że gdy pojawia się zapytanie, które musi przechowywać coś w tempdb SQL Server i nie ma wystarczającej ilości pamięci RAM, SQL Server ma 2 możliwości:

1) aby zwolnić niektóre buforowane dane i użyć oszczędzonej pamięci RAM zamiast tempdb, aby uniknąć zapisywania na dysku

2) zachowuj buforowane dane dla przyszłych zapytań i zacznij używać tempdb, co powoduje, że zapis spowalnia dysk.

Nie wiem, jakiego wyboru dokona SQL Server w tej sytuacji, ale chciałbym, aby dokonał wyboru nr 1, ponieważ zależy mi tylko na wydajności pierwszych zapytań (dziewiczych), ponieważ nigdy więcej nie wysyłam tego samego zapytania do SQL Server (chociaż mogę wysłać podobne zapytanie).

Jaka jest strategia buforowania programu SQL Server dla tego scenariusza?

W jaki sposób równoważy użycie pamięci RAM między unikaniem tempdb dla pierwotnych zapytań a szybkością drugiego zapytania?

Czy można skonfigurować program SQL Server w taki sposób, aby dokonał wyboru nr 1? Jeśli tak to jak?

Jak inaczej mogę zwiększyć wydajność wszystkich dziewiczych zapytań SQL?

Ponieważ nie znam strategii buforowania programu SQL Server, chcę umieścić bazę danych na dysku RAM. Zapewni to, że każde pierwotne zapytanie ma wysoką prędkość ładowania niebuforowanych danych, nawet jeśli SQL Server zawsze dokonuje wyboru nr 1. Ryzyko polega na tym, że SQL Server może zacząć używać więcej tempdb z mniej dostępną pamięcią RAM (pozostało tylko 16 GB po użyciu 16 GB dla dysku RAM), jeśli nadal wybierze numer 2, co spowolni te dziewicze zapytania, które powodują rozlanie tempdb.

Interesuje mnie rozwiązanie dla SQL 2008 R2, ale chyba jest tak samo dla SQL 2008, SQL 2005 i może to być SQL 2000.

Wyjaśnienia:

Na tym urządzeniu nie działają żadne inne aplikacje, jest on dedykowany dla SQL Server . Strona internetowa działa na osobnym polu.

Jest to SQL Server 2008 R2 Standard Edition 64-bitowy w systemie Windows Server 2008 R2 Enterprise 64-bitowy.

Uruchamiam tylko zapytania tylko do odczytu, a baza danych jest ustawiona tylko do odczytu .

Załóżmy, że istnieją już dobre indeksy . To pytanie dotyczy SQL Server dokonującego wyboru nr 1 vs. wyboru nr 2, jak to zrobić, czy istnieje sposób, aby to kontrolować i czy Dysk RAM pomaga w dokonaniu właściwego wyboru w przypadku dziewiczych zapytań.

alpav
źródło
Co sprawia, że ​​myślisz, że tempdb jest używany, nawet jeśli nie tworzysz tabel tymczasowych? Czy używasz odrębnych lub grupuj według tabel?
cieśnina darina
3
32/64 bit? Fizycznie czy wirtualnie? Czy ten serwer jest dedykowany dla SQL Server, czy też używasz IIS lub innych aplikacji na tym samym urządzeniu? Czy przeprowadziłeś już analizę planu wykonania zapytania? Czy możesz zamieścić przykładowe zapytania i / lub plany wykonania? I jeszcze jedno na szczęście ... postępuj zgodnie ze wskazówkami Kendry dotyczącymi rejestrowania sp_whoisactive podczas działania zapytania dotyczącego problemu i opublikuj dane wyjściowe.
Mark Storey-Smith
@darinstrait Najprawdopodobniej wyjaśnienie byłoby swego rodzaju wyciekami mieszania.
Mark Storey-Smith

Odpowiedzi:

7

Twoje pytanie można w zasadzie przeformułować jako „Jak działa przyznawanie pamięci zapytań?”. Dobra lektura na ten temat to Zrozumienie przyznawania pamięci serwera SQL . Przed uruchomieniem zapytania może być konieczne przyznanie pamięci na sortowanie i mieszanie oraz inne operacje wymagające pamięci. Przydział pamięci jest wartością szacunkową . Na podstawie aktualnego stanu systemu (liczba uruchomionych i oczekujących żądań, dostępna pamięć itp.) System przyznaje kwerendie przydział pamięci do wymaganej ilości. Po przyznaniu pamięci kwerenda rozpoczyna wykonywanie (może potrzebować poczekać w przerażającej kolejce „semafor zasobów”, zanim otrzyma przydział). Przy wykonywaniu gwarantowane jest przyznanie pamięci przez system. Tę ilość pamięci można współdzielić ze stronami danych (ponieważ zawsze można je opróżnić na dysk), ale nigdy przy innym użyciu pamięci (tzn. Nie można jej „ukraść”). Kiedy więc zapytanie zacznie pytać o przyznaną pamięć od jego przyznania, silnik wdroży coś, co nazwiesz „strategią nr 1”: strony danych mogą zostać eksmitowane (opróżnione, jeśli są brudne), aby nadać zapytaniu obiecaną pamięć. Teraz, jeśli oszacowanie było prawidłowe, a przydział wynosił 100% żądanej pamięci, zapytanie nie powinno się „rozlać”. Ale jeśli oszacowanie było niepoprawne (sprowadza się do szacunków liczności, dlatego podlega nieaktualnym statystykom) lub jeśli zapytanie nie otrzymało całej kwoty, o którą prosiło, zapytanie zostanie „rozlane”. To właśnie wtedy pojawia się tempdb, a wydajność zwykle to czołgi.

Jedynym pokrętłem, które masz do dyspozycji, które kontroluje coś w tym procesie, jest gubernator zasobów . Ponieważ RG można użyć do określenia ustawienia MIN dla puli, można go użyć do zarezerwowania pamięci dla określonego obciążenia, tak aby faktycznie otrzymał przyznanie pamięci, o które prosi. Oczywiście po przeprowadzeniu właściwego dochodzenia, które pokazuje, że winowajcami zmniejszone granty pamięci , i oczywiście po ocenie wpływu na inne obciążenia. I oczywiście przetestowane.

Teraz wróćmy do twojego pierwotnego pytania. Jeśli twoje dochodzenie jest prawidłowe (bardzo duże, jeśli), chciałbym wskazać dwa problemy:

  • uruchamiasz w zapytaniach produkcyjnych, które wymagają przyznania pamięci dla strony internetowej . To wielkie nie-nie. Przydziały pamięci wskazują na zapytania analityczne, w których nie ma miejsca na obsługę żądań HTTP.
  • Twoje zapytania prawdopodobnie nie powodują otrzymania żądanego przydziału pamięci. Ponownie, jeszcze więcej nie-nie dla obciążenia krytycznego dla opóźnień, jak strony internetowe.

To mówi mi, że masz podstawowy problem projektowy i architektoniczny. Witryny sieci Web są oparte na opóźnieniach i powinny tworzyć obciążenie podobne do OLTP, bez przydziałów pamięci i bez presji pamięci na zapytania. Nie wspominając o żadnych wyciekach. Zapytania analityczne powinny być uruchamiane w zadaniach offline i przechowywać wstępnie przetworzone wyniki w celu zapewnienia ich szybkiej dostępności, gdy żądają tego żądania HTTP.

Remus Rusanu
źródło
@ Mark: Większość zapytań nie wymaga przyznania pamięci. Tylko kilku operatorów (w szczególności sortowanie i łączenie mieszające) potrzebuje bufora roboczego i dlatego żąda przyznania. Jest to standardowa „nomenklatura”. Być może zastanawiasz się nad środowiskiem wykonywania i planem wykonania zapytania, którego każde zapytanie wymaga jednego i zawiera ono trochę pamięci. Przydział pamięci jest znacznie większy (MB). Po drugie, spójrz na sys.dm_exec_query_memory_grants: masz requested(maksimum), required(min) i granted(rzeczywiste).
Remus Rusanu,
Przeprosiny. Skądś wziąłem, że minimum na zapytanie przydzielono temu samemu urzędnikowi pamięci, co było niepoprawne.
Mark Storey-Smith
Nadal nie jestem pewien, czy zgadzam się z Twoimi dwoma punktami. Wszelkiego rodzaju trywialne operacje łączenia i mieszania wymagają dotacji na minimalnym poziomie, więc sugerowanie, że należy je całkowicie wyeliminować, wydaje się nadmierne. To, że wycieki do tempdb z niewystarczających dotacji są czerwoną flagą, jest z pewnością rozsądne, ale ogólny zakaz jakiejkolwiek operacji wymagającej dotacji może ustawić wiele osób na niepotrzebnej ścieżce optymalizacji wyprzedzającej?
Mark Storey-Smith
OP twierdzi, że ma wszystkie niezbędne indeksy. Jeśli to prawda, a obciążenie ma wystarczająco dużo problemów z przyznaniem pamięci (a nawet rozlaniem), aby były zauważalne, to powiedziałbym, że obciążenie jest zbyt analityczne dla strony internetowej . Ostatecznie optymalizacja wydajności jest zawsze grą badawczą mającą na celu ustalenie pierwotnej przyczyny. Wszystkie stwierdzenia ogólne i zakazy zawsze znajdują przeciwny przykład, który dowodzi, że się mylą, to jest dane. Czy PO ma problem z projektem, który powoduje zbyt analityczne obciążenie pracą? Nie wiem Czy myślę, że tak? Powiedziałbym 87,5% zaufania tak.
Remus Rusanu,
@Remus: Twoje przypuszczenia były dobre, moje zapytania na stronie są w 100% analityczne. Pozwala użytkownikom konstruować dowolne zapytania w interfejsie użytkownika, aby wysyłać dowolną kombinację filtrów, agregatów i grupowań do SQL Server (co oczywiście utrudnia indeksowanie). Tak, mógłbym je uruchomić w trybie asynchronicznym, zapisując wyniki do późniejszego pobrania, ale celem jest, aby każde zapytanie działało tak szybko, że wynik jest natychmiast dostępny po 2-10 sekundach, a także zapytania analityczne to jedyna funkcja tej witryny , Myślę, że uczynienie ich asynchronicznymi ma sens tylko wtedy, gdy istnieją inne zapytania, które nie są analityczne.
alpav
3

Nie wspomniałeś o tym, jakie zapytania są uruchamiane względem bazy danych i czy istnieją odpowiednie indeksy, aby przyspieszyć wydajność twoich zapytań.

Musisz także upewnić się, czy na tym samym urządzeniu działają inne aplikacje. Mimo że pudełko ma 32 GB pamięci RAM, ustaw dowolne ustawienie maksymalnej pamięci na serwerze bazy danych, aby ustawić dowolny sztuczny limit. Jeśli na tym samym serwerze działają aplikacje, wówczas SQL i inne aplikacje mogą konkurować o zasoby i zauważ, że SQL jest bardzo wymagający pamięci.

SQL Server użyje tempdb do wewnętrznego sortowania lub łączenia skrótów / agregatów lub operatorów buforowania itp. I nie można kontrolować tego zachowania. Możesz ograniczyć ilość zwracanych danych.

Czy sprawdziłeś statystyki oczekiwania w tym polu? Za każdym razem, gdy SQL Server czeka na zasób, SQL Server śledzi zasób oczekiwania i analizowanie tych informacji pomaga.

Spójrz na zapytania diagnostyczne Glenn Berry, a to będzie dobry początek.

Zobacz także PARAMETERIZATION FORCED, jak wspomniano w http://weblogs.sqlteam.com/dang/archive/2009/06/27/Forced-Parameterization-A-Turbo-Button.aspx

Sankar Reddy
źródło
ok, załóżmy, że istnieją już właściwe indeksy. Zapomniałem wspomnieć, że jest to baza danych tylko do odczytu z zapytaniami tylko do odczytu i na serwerze SQl Server nie działa żadna inna aplikacja.
alpav
Czy Twoje statystyki są aktualne? Bazy danych tylko do odczytu nie mogą tworzyć statystyk, jeśli ich brakuje lub są nieaktualne. Czy Twoje dane są wypaczone lub mają unikalne wartości dla klucza. Istnieje wiele czynników, które mogą powodować takie zachowanie.
Sankar Reddy
Co rozumiesz przez „to zachowanie”? Nie wspomniałem, że coś idzie nie tak. Chcę tylko zwiększyć wydajność w moich szczególnych okolicznościach. Program SQL Server jest zoptymalizowany do działania w dowolnej sytuacji, ale może, ale nie musi, działać najlepiej w mojej sytuacji. Nie jestem pewien, czy mogę zaufać programowi SQL Server, aby dokonać zrównoważonego wyboru nr 1 w stosunku do nr 2. Za każdym razem, gdy umieszczam na nim nowe dane, uruchamiam sp_updatestats.
alpav
2
Kiedy uruchamiasz sp_updatestats, jaki jest wybrany współczynnik próbkowania. Domyślny współczynnik jest bardzo przykładowy i zależy od wielkości indeksu. Jeśli twoje zapytania przeszukują głównie (tylko) nowe dane, a nawet jeśli robisz sp_updatestats, SQL Server nie może podejmować dobrych decyzji dotyczących planów wykonania.
Sankar Reddy
2

To pytanie brzmi obecnie jak rozwiązanie szukające problemu. Zdecydowałeś, że dyskiem RAM jest rozwiązanie i chcesz, aby ktoś potwierdził ten wybór. Przepraszam, nie nastąpi.

Jeśli zmierzyłeś i zaobserwowałeś wyciek do tempdb, prawie na pewno będzie to spowodowane operacją sortowania lub mieszania i niedostatecznym przyznaniem pamięci zapytania. W zależności od ilości danych, które mają być przetwarzane, może to być nieuniknione, ale istnieje duże prawdopodobieństwo, że zapytanie i / lub indeksacja mogą zostać ulepszone, aby tego uniknąć.

Rzuć okiem na Zarządzanie buforami, aby lepiej zrozumieć, w jaki sposób SQL Server zarządza pamięcią, oraz SQL Server Zarządzanie pamięcią Objaśniono niektóre podstawowe narzędzia i zapytania DMV, aby zrozumieć, gdzie przydzielona jest pamięć.

Jak inaczej mogę zwiększyć wydajność wszystkich dziewiczych zapytań SQL?

To jest duży temat. Opublikuj zapytanie i zaplanuj, a otrzymasz ukierunkowaną informację zwrotną.

Mark Storey-Smith
źródło