Database
 sql >> Baza danych >  >> RDS >> Database

Przycinanie tłuszczu dziennika transakcji

W wielu obciążeniach SQL Server, zwłaszcza OLTP, dziennik transakcji bazy danych może być wąskim gardłem, które wydłuża czas realizacji transakcji. Większość ludzi zakłada, że ​​podsystem I/O jest prawdziwym wąskim gardłem, ponieważ nie jest w stanie nadążyć za ilością dziennika transakcji generowanego przez obciążenie.

Opóźnienie zapisu dziennika transakcji

Opóźnienie operacji zapisu do dziennika transakcji można monitorować za pomocą sys.dm_io_virtual_file_stats DMV i skorelowane z WRITELOG czeka, które występują w systemie. Nagrałem film demonstracyjny z analizy I/O dziennika transakcji w 2011 roku, więc nie będę tego wszystkiego powtarzał w tym poście. Możesz pobrać wideo tutaj, a kod demo tutaj (odpowiedni do natychmiastowego uruchomienia w produkcji).

Jeśli opóźnienie zapisu jest wyższe niż można by się spodziewać w przypadku podsystemu we/wy, podsystem we/wy nie może nadążyć, tak jak jest to ogólne założenie. Czy to oznacza, że ​​podsystem I/O wymaga jednak ulepszenia? Niekoniecznie.

W wielu systemach klienckich odkryłem, że znaczna część generowanych rekordów dziennika jest niepotrzebna, a jeśli możesz zmniejszyć liczbę generowanych rekordów dziennika, zmniejszasz ilość dziennika transakcji zapisywanego na dysku. Powinno to przełożyć się na zmniejszenie opóźnień zapisu, a tym samym skrócić czas realizacji transakcji.

Istnieją dwie główne przyczyny generowania dodatkowych rekordów dziennika:nieużywane indeksy nieklastrowane oraz fragmentacja indeksów.

Nieużywane indeksy nieklastrowane

Za każdym razem, gdy rekord jest wstawiany do tabeli, rekord musi zostać wstawiony do każdego indeksu nieklastrowanego zdefiniowanego w tabeli (z wyjątkiem indeksów filtrowanych z odpowiednimi filtrami, które od tego momentu pominięto). Oznacza to, że dla każdego wstawienia tabeli generowane są dodatkowe rekordy dziennika, co najmniej jeden na indeks nieklastrowany. To samo dotyczy usuwania rekordu z tabeli – pasujące rekordy muszą zostać usunięte ze wszystkich indeksów nieklastrowanych. W przypadku aktualizacji rekordu tabeli rekordy indeksu nieklastrowego są aktualizowane tylko wtedy, gdy kolumny klucza indeksu nieklastrowego lub zawarte kolumny były częścią aktualizacji.

Operacje te są oczywiście niezbędne, aby każdy indeks nieklastrowany był poprawny w odniesieniu do tabeli, ale jeśli indeks nieklastrowy nie jest używany przez obciążenie, to operacje i tworzone przez nie rekordy dziennika są niepotrzebnym obciążeniem. Co więcej, jeśli te nieużywane indeksy ulegną fragmentacji (co omówię w dalszej części tego postu), wówczas będą na nich działać również regularne zadania konserwacji indeksów, generując jeszcze więcej rekordów logów (z indeksu REBUILD lub REORGANIZE operacji) całkowicie niepotrzebnie.

Nieużywane indeksy pochodzą z różnych źródeł, na przykład ktoś omyłkowo tworzy indeks dla każdej kolumny tabeli, ktoś tworzy każdy indeks sugerowany przez brakujące indeksy DMV lub ktoś tworzy wszystkie indeksy sugerowane przez Doradcę dostrajania bazy danych. Może się również zdarzyć, że zmieniły się charakterystyki obciążenia, a zatem to, co kiedyś było użytecznymi indeksami, nie jest już używane.

Niezależnie od tego, skąd pochodzą, nieużywane indeksy należy usunąć, aby zmniejszyć ich obciążenie. Możesz określić, które indeksy są nieużywane za pomocą DMV sys.dm_db_index_usage_stats, i polecam przeczytać posty moich kolegów Kimberly L. Tripp (tutaj) i Joe Sacka (tu i tutaj), ponieważ wyjaśniają, jak prawidłowo korzystać z DMV.

Fragmentacja indeksu

Większość ludzi myśli o fragmentacji indeksu jako o problemie, który wpływa na zapytania, które muszą czytać duże ilości danych. Chociaż jest to jeden z problemów, które może powodować fragmentacja, fragmentacja jest również problemem ze względu na sposób jej występowania.

Fragmentacja jest spowodowana operacją zwaną podziałem strony. Najprostszą przyczyną podziału strony jest sytuacja, w której rekord indeksu musi zostać wstawiony na określonej stronie (ze względu na jego wartość klucza), a na stronie nie ma wystarczającej ilości wolnego miejsca. W tym scenariuszu będą miały miejsce następujące operacje:

  • Nowa strona indeksu została przydzielona i sformatowana
  • Niektóre rekordy z pełnej strony są przenoszone na nową stronę, tworząc w ten sposób wolne miejsce na wymaganej stronie
  • Nowa strona jest połączona ze strukturą indeksu
  • Nowy rekord jest wstawiany na wymaganej stronie

Wszystkie te operacje generują rekordy dziennika, a jak można sobie wyobrazić, może to być znacznie więcej niż jest to wymagane do wstawienia nowego rekordu na stronie, która nie wymaga podziału strony. W 2009 roku napisałem na blogu analizę kosztów podziału strony pod kątem dziennika transakcji i znalazłem przypadki, w których podział strony generował ponad 40 razy więcej dziennika transakcji niż zwykła wstawka!

Pierwszym krokiem w redukcji dodatkowych kosztów jest usunięcie nieużywanych indeksów, jak opisałem powyżej, aby nie generowały podziałów stron. Drugim krokiem jest zidentyfikowanie pozostałych indeksów, które ulegają fragmentacji (a więc muszą cierpieć na podziały stron) za pomocą sys.dm_db_index_physical_stats DMV (lub nowy SQL Sentry Fragmentation Manager) i proaktywne tworzenie w nich wolnego miejsca za pomocą współczynnika wypełnienia indeksu. Współczynnik wypełnienia instruuje SQL Server, aby pozostawił puste miejsce na stronach indeksu, gdy indeks jest budowany, przebudowywany lub reorganizowany, tak aby było miejsce na wstawianie nowych rekordów bez konieczności dzielenia strony, co zmniejsza liczbę generowanych dodatkowych rekordów dziennika.

Oczywiście nic nie jest za darmo – kompromis podczas używania współczynników wypełnienia polega na tym, że aktywnie udostępniasz dodatkowe miejsce w indeksach, aby zapobiec generowaniu większej liczby rekordów dziennika – ale zwykle jest to dobry kompromis. Wybór współczynnika wypełnienia jest stosunkowo łatwy i pisałem o tym tutaj.

Podsumowanie

Zmniejszenie opóźnienia zapisu pliku dziennika transakcji nie zawsze oznacza przejście do szybszego podsystemu we/wy lub segregację pliku we własnej części podsystemu we/wy. Dzięki prostej analizie indeksów w Twojej bazie danych możesz znacznie zmniejszyć liczbę generowanych rekordów dziennika transakcji, prowadząc do proporcjonalnego zmniejszenia opóźnienia zapisu.

Istnieją inne, bardziej subtelne problemy, które mogą wpływać na wydajność dziennika transakcji, i omówię je w przyszłym poście.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przekształć dane ODBC w CloverDX

  2. Wykonywanie audytu zmian danych przy użyciu tabeli czasowej

  3. =) Operator dla początkujących

  4. Samouczek łączenia SQL

  5. Jak usunąć rewizje postów za pomocą WP-CLI