Kiedy można zmniejszyć bazę danych?

43

Wiem, że shrink to diabeł: odwraca kolejność stron i jest odpowiedzialny za raka skóry, fragmentację danych i globalne ocieplenie. Lista jest długa ... Mówiąc to, powiedzmy, że mam bazę danych o pojemności 100 GB i usuwam 50 GB danych - nie z jednej tabeli, ale ogólne czyszczenie starych danych na poziomie całej bazy danych, obejmujące 90% tabele - czy stanowi to odpowiedni przypadek użycia do zmniejszenia bazy danych?

Jeśli nie, jakie odpowiednie kroki należy podjąć, aby wyczyścić dom po usunięciu tak wysokiego odsetka danych z bazy danych? Mogę wymyślić dwa: odbudować indeksy i zaktualizować statystyki. Co jeszcze?

bumble_bee_tuna
źródło

Odpowiedzi:

13

Naprawdę nigdy nie zaleca się reorganizacji i zmniejszania.

Jeśli możesz przenieść aplikacje, które baza danych obsługuje w trybie offline, możesz przyspieszyć proces i zmniejszyć fragmentację indeksów, usuwając wszystkie indeksy i ograniczenia klucza podstawowego / obcego przed zmniejszeniem (oznacza to, że będzie mniej danych do przenoszenia, ponieważ tylko strony danych zostaną przetasowane, a nie nieistniejące już strony indeksu, co przyspieszy proces), a następnie ponownie utworzą wszystkie indeksy i klucze.

Ponowne odtworzenie indeksów po zmniejszeniu oznacza, że ​​nie powinny one być znacznie pofragmentowane, a ich zniknięcie podczas zmniejszania oznacza przebudowanie ich nie pozostawi wielu małych „dziur” w przydziale stron w plikach, które mogą zaprosić do fragmentacji później.

Inną opcją, jeśli możesz wyłączyć aplikacje, jest migracja wszystkich danych do nowej bazy danych o tej samej strukturze. Jeśli proces kompilacji jest solidny, powinieneś być w stanie szybko zbudować tę pustą bazę danych, jeśli nie, utwórz ją z bieżącej bazy danych (przywróć kopię zapasową bieżącej bazy danych, skróć / usuń całą zawartość tabel i wykonaj pełne zmniejszanie).

Nadal możesz chcieć upuścić wszystkie indeksy w miejscu docelowym i odtworzyć je później, ponieważ może to być o wiele bardziej wydajne przy zmianie dużej ilości indeksowanych danych (w tym przypadku 100%). Aby przyspieszyć proces kopiowania, umieść pliki danych docelowej bazy danych na różnych fizycznych dyskach do źródła (chyba że używasz dysków SSD, w którym to przypadku nie musisz martwić się o ograniczenie ruchów głowy), możesz je przenieść po zakończeniu do lokalizacji źródłowej.

Ponadto, jeśli utworzysz miejsce docelowe jako nowe (zamiast pustego miejsca na kopię źródła), utwórz go z początkowym rozmiarem, który będzie zawierał wszystkie bieżące dane plus wzrost o kilka miesięcy - dzięki temu dane będą znowu trochę szybsze, ponieważ nie będzie od czasu do czasu przydzielać nowej przestrzeni.

Może to być lepsze niż użycie funkcji zmniejszania, ponieważ migracja danych do świeżej bazy danych replikuje zamierzone działanie operacji zmniejszania, ale potencjalnie przy znacznie mniejszej fragmentacji (co jest niezamierzoną konsekwencją reorganizacji i zmniejszenia). Zmniejszenie po prostu pobiera bloki z końca pliku i umieszcza je w pierwszej przestrzeni bliżej początku, nie próbując utrzymać powiązanych danych razem.

Podejrzewam, że wynik będzie również bardziej wydajny pod względem przestrzennym, ponieważ prawdopodobnie później będzie mniej stron częściowo wykorzystywanych. Zmniejszenie spowoduje po prostu przenoszenie częściowo używanych stron, przenoszenie danych z większym prawdopodobieństwem spowoduje powstanie pełnych stron, szczególnie jeśli wstawisz do miejsca docelowego w kolejności klucza / indeksu klastrowanego (gdzie tabela ma jeden) i utworzysz inne indeksy po migracji wszystkich danych.

Oczywiście, jeśli nie możesz w ogóle przełączyć aplikacji w tryb offline, po prostu zmniejszanie jest jedyną opcją, więc jeśli naprawdę musisz odzyskać miejsce, idź z tym. W zależności od danych, wzorców dostępu, wielkości wspólnego zestawu roboczego, ilości pamięci RAM serwera itd. Dodatkowe fragmentowanie wewnętrzne może nie być aż tak znaczące.

W przypadku operacji kopiowania równie dobrze działałby SSIS lub podstawowy T-SQL (opcja SSIS może być mniej wydajna, ale potencjalnie łatwiejsza w utrzymaniu później). Jeśli utworzysz relacje FK na końcu wraz z indeksami, możesz zrobić proste „dla każdej tabeli, skopiuj” w obu przypadkach. Oczywiście jednorazowo reorganizacja kurczenia się + jest prawdopodobnie w porządku, ale lubię straszyć ludzi, aby nigdy nie brali pod uwagę regularnych skurczów! (Wiem, że ludzie planują je codziennie).

David Spillett
źródło
16

Czy baza danych znów wzrośnie? Jeśli tak, to wysiłek, który włożysz w operacje zmniejszania, będzie po prostu marnotrawstwem, ponieważ kiedy zmniejszysz rozmiar pliku, a następnie dodasz więcej danych, plik będzie musiał ponownie wzrosnąć, i transakcje muszą czekać na wzrost. Jeśli masz nieoptymalne ustawienia automatycznego wzrostu i / lub powolny dysk, ta aktywność wzrostu będzie bardzo bolesna.

Jeśli zmniejszysz bazę danych, do czego zamierzasz wykorzystać zwolnione miejsce na dysku? Ponownie, jeśli zamierzasz zachować tę przestrzeń wolną na wypadek, gdyby baza danych znów rosła, to po prostu kręcisz się.

To, co możesz rozważyć, skoro masz już tyle wolnego miejsca w pliku, to przebudowywanie indeksów, aby były lepiej zoptymalizowane (i będzie to o wiele mniej bolesne, gdy będziesz mieć na to miejsce - pomyśl o próbie zmiany swetra w małej szafie w porównaniu do dużej sypialni).

Więc jeśli nie była to poważna operacja czyszczenia i naprawdę nie będziesz ponownie zwiększać do tego samego poziomu danych, po prostu zostawię to tak, jak jest i skupię się na innych obszarach optymalizacji.

Aaron Bertrand
źródło
@Aarron Bertrand Cóż, zajęło 10 lat, aby uzyskać tak duży dysk. Trochę to niepokoi, ponieważ chciałbym go ustawić w stanie stałym. Myślałem o zmniejszeniu się do 60 GB przy wzroście 5 GB. Naprawdę jedyne, co zalecasz, to odbudowanie indeksów, co? Myślałem, że ludzie będą mieli więcej rekomendacji.
bumble_bee_tuna
I poleciłbym przebudowę tylko, jeśli będą tego potrzebować. Ale zrobiłbym to zanim zmniejszysz plik. Naprawdę nie mogę wymyślić niczego poza moją głową, co zrobiłbyś z wolną przestrzenią, która zapewniłaby optymalizację wydajności w ogólnym przypadku ...
Aaron Bertrand
2

Jeśli zabraknie Ci miejsca, a twoje dane nie powinny być tak duże, to skurcz się, ale odbuduj swoje indeksy z odpowiednimi współczynnikami wypełnienia, które pozwalają na typowy wzrost.

Jeśli Twoim ostatecznym celem jest zmniejszenie rozmiaru kopii zapasowej, upewnij się, że wdrożono kompleksową strategię tworzenia kopii zapasowych, aby wyczyścić dziennik transakcji, a podczas tworzenia kopii zapasowej bazy danych użyj opcji kompresji.

Nie polecałbym automatycznego wzrostu 5 GB, chyba że zwykle spodziewasz się częstego wzrostu 5 GB. W przeciwnym razie mogą występować sporadyczne problemy z wydajnością. Rozmiar danych powinien być najpierw ustawiony zgodnie z Twoim zdaniem na rok, a Auto Growth powinien być ustawiony na rozmiar, który testowałeś, nie wpływa na wydajność operacyjną. Zobacz Nie dotykaj tego przycisku zmniejszania bazy danych w programie SQL Server! Mike Walsh.

Odbudowywanie indeksów przed zmniejszeniem powoduje, że indeksy są źle ułożone. Nie jest dobrze odbudowywać, a potem zmniejszać. Zmniejszanie powoduje zniekształcanie indeksów w celu odzyskania miejsca - tak więc wcześniejsze odbudowywanie, a następnie zmniejszanie nie ma sensu. Zobacz Kiedy używać funkcji Auto Shrink Thomasa LaRocka.

GilesDMiddleton
źródło
Jeśli zmniejszysz, a następnie przebudujesz indeksy, plik danych będzie musiał ponownie wzrosnąć, aby pomieścić kopię danych użytych do odbudowania. Chociaż w tym przypadku nie będzie tak duży jak oryginalny plik danych, nadal będzie się rozwijał i wydaje się, że przynosi efekt przeciwny do zamierzonego. Przebudowa, gdy jest wolne miejsce, będzie szybsza (nie wymaga automatycznego wzrostu) i ogólnie będzie lepsza niż sugerujesz, w jaki sposób układa się strony dla nowej kopii indeksu, i podejrzewam, że w większości przypadków będzie to ogólnie krótsze i prowadzić do takiego samego lub lepszego odzyskiwania miejsca na dysku. Może czas na jakieś testy.
Aaron Bertrand
I oczywiście zakłada to, że indeksy danych, które pozostaną, będą musiały zostać odbudowane - być może już są w całkiem dobrym stanie.
Aaron Bertrand
1

Nie wiem, czy to zadziałałoby lepiej niż ponowne indeksowanie po zmniejszeniu, ale inną opcją byłoby utworzenie nowego pliku danych o odpowiednim rozmiarze i przeniesienie do niego wszystkich danych. W takim przypadku najpierw zrobiłbym reindeks, abyś wiedział, jaki jest rzeczywisty rozmiar danych. Jednym problemem jest to, że jeśli jest to pierwszy plik w podstawowym pliku danych, nie sądzę, że można go opróżnić. Powinieneś być w stanie go zmniejszyć, a następnie przenieść dane z powrotem, aby uniknąć odwrócenia strony. Jeśli jednak chcesz przejść do stanu półprzewodnikowego, nie powinno to mieć większego znaczenia.

cfradenburg
źródło
1

Wracając do tego DROGA późno. Jednak od dłuższego czasu zastanawiamy się i testujemy użycie kurczenia w naszych środowiskach testowych. Zgodnie z tematem zdarzają się sytuacje, w których kurczenie się jest realną opcją. Ale wiedza o tym, kiedy i jak go zastosować, jest niezbędna do prawidłowego wykonania zarówno w długim, jak i krótkim okresie.

W naszym scenariuszu ostatnio dodaliśmy wiele zmian do naszej dużej bazy danych, w tym kompresję, partycjonowanie, archiwizację i zwykłe stare usuwanie zbędnych danych. W rezultacie wykorzystana część naszego podstawowego pliku danych spadła do mniej niż połowy tego, co kiedyś. Ale po co nosić cały ten bagaż? Zwłaszcza, że ​​w przeciwieństwie do niektórych artykułów w Internecie, rozmiar twoich plików danych BEZPOŚREDNIO KORELUJE Z CZASEM PRZECHOWYWANIA / PRZYWRACANIA. Wynika to z faktu, że w przeciwieństwie do wielu artykułów, w rzeczywistych scenariuszach ładuje się więcej danych na dowolnej stronie niż tylko rzeczy, które możesz usunąć.

Co więcej, otwiera to świetny scenariusz kurczenia się:

  1. Utwórz skrypt, który znajdzie wszystkie obiekty i ich grupy plików w bazie danych (mnóstwo przykładów online), użyj tego do tworzenia klauzul upuszczania, a także do tworzenia definicji dla każdego z twoich indeksów i ograniczeń.
  2. Utwórz nowy plik i grupa plików i ustaw ją jako domyślną.
  3. Usuń wszystkie indeksy nieklastrowane (uwaga, niektóre indeksy mogą być ograniczeniami).
  4. Utwórz klastrowane indeksy w nowej grupie plików za pomocą DROP_EXISTING = ON (co przy okazji jest niezwykle szybką, minimalnie rejestrowaną operacją na początek w porównaniu z wieloma alternatywami).
  5. Odtwórz swoje nieklastrowane indeksy.
  6. Na koniec SHRINK stary plik danych (zwykle PODSTAWOWY).

W ten sposób jedynymi pozostałymi danymi byłyby obiekty systemowe DB, statystyki, procedury i tak dalej. Zmniejszenie powinno być znacznie, DUŻO szybsze, i nie ma potrzeby dalszego utrzymywania indeksu na głównych obiektach danych, które zostaną starannie utworzone w celu minimalizacji ryzyka przyszłej fragmentacji.

Kahn
źródło