Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Zawężenie typów danych na bardzo dużej tabeli

Po pierwsze, dziękuję za zrobienie tego. Jest to tak oczywista wygrana, że ​​wielu nie dostrzegłoby w niej dużej wartości, ale będzie warto :). Sprawiamy, że świat staje się trochę zdrowszy.

Odnośnie IsActive bycie wartością logiczną. Domyślam się, że myślisz o uczynieniu z tego BIT pole. To może być droga, ale czasami lepiej jest użyć TINYINT ponieważ istnieje możliwość rozszerzenia znaczenia na więcej niż 2 stany. W takim przypadku naprawdę staje się bardziej z StatusID . Zwykle jest to przypadek, gdy coś zaczyna się w uproszczeniu jako Aktywne / Nieaktywny , ale później może usunięte i/lub inne. Z perspektywy rozmiaru TINYINT ma zawsze 1 bajt. Z drugiej strony BIT wynosi 1 bajt do 8 BIT pola . Znaczenie, jeden BIT pole to 1 bajt, 2 BIT pola to również jeden bajt i tak dalej aż do 8 BIT pola są przechowywane w jednym bajcie. Tak więc nie ma oszczędności miejsca, wybierając BIT ponad TINYINT gdy tabela ma tylko 1 BIT pole. Po prostu coś do rozważenia.

Jak widzieliście, zrobienie ALTER TABLE to trochę za dużo jak na duży stół. Jedną z opcji, choć niezbyt dobrą, jest dodanie NOT NULL pole--Number_1new --z DEFAULT wartość (będzie to natychmiastowe ze względu na domyślną, przynajmniej począwszy od SQL 2012), której żaden z nich nie miałby naturalnie (np. 255), a następnie powoli migruje wartości, w pętli, jak w:

UPDATE TOP (5000) tab
SET tab.Number_1new = tab.Number_1
FROM [table] tab
WHERE tab.Number_1new = 255;

A kiedy to zrobisz, wykonaj:

sp_rename 'table.Number_1', 'Number_1old', 'COLUMN';
sp_rename 'table.Number_1new', 'Number_1', 'COLUMN';

Oczywiście najlepiej zapakować to w TRANSAKCJĘ, a to w TRY/CATCH. Gdy powiązany kod zostanie zaktualizowany i wszystko przetestowane, a dane wyglądają dobrze, możesz usunąć Number_1old kolumna.

Jednak najlepszym sposobem, jaki znalazłem, jest utworzenie nowej tabeli, powolne przeniesienie danych, a następnie zamiana tabel i kodu w tym samym czasie. Opisałem kroki w artykule na temat SQL Server Central:Restrukturyzacja 100 milionów wierszy (lub więcej) Tabele w sekundach. SRSLY! (wymagana bezpłatna rejestracja). Na wypadek, gdyby pojawiły się problemy z dotarciem do tego artykułu, oto podstawowe kroki:

  1. Utwórz nową tabelę o idealnej strukturze — [tableNew]. Jeśli korzystasz z Enterprise Edition, rozważ włączenie kompresji ROW lub PAGE, ponieważ czasami mogą one pomóc. Ale najpierw zrób trochę badań, ponieważ zdarzają się sytuacje, w których mają one negatywny wpływ. W witrynie MSDN dostępna jest dokumentacja, która pomoże Ci to rozgryźć, a także niektóre narzędzia pomagające oszacować potencjalne oszczędności. Ale nawet jeśli włączysz kompresję, nie postrzegałbym tej akcji jako zastąpienia projektu, który tutaj robisz.
  2. Dodaj wyzwalacz AFTER UPDATE, DELETE na [table], aby zachować synchronizację zmian (ale nie musisz się martwić o nowe wiersze)
  3. Utwórz zadanie agenta SQL, które partiami przenosi brakujące wiersze. Zrób to w pętli, która wykonuje INSERT INTO [tableNew] (Columns) SELECT TOP (n) Columns FROM [table] WHERE ?? ORDER BY ??
  4. Klauzule WHERE i ORDER BY zależą od sytuacji. Powinny być nastawione na jak najlepsze wykorzystanie indeksu klastrowego. Jeśli indeks klastrowy nowej tabeli jest strukturalnie taki sam jak stara/bieżąca tabela, to na początku każdej pętli możesz uzyskać MAX([id]) z [tableNew] i użyć go do pobrania tabeli WHERE table.[id] > @MaxIdInTableNew ORDER BY table.[id] .
  5. Utwórz nową tabelę, wyzwalacz w bieżącej tabeli i zadanie SQL Agent mniej więcej tydzień przed wykonaniem pełnego przełączenia. Te ramy czasowe mogą się zmienić w zależności od Twojej sytuacji, ale pamiętaj, aby dać sobie dużo czasu. O wiele lepiej jest zakończyć migrację wierszy i mieć tylko kilka ściekających naraz, niż być 100 tys.
  6. Jeśli plan zakłada migrację innych powiązanych tabel (odniesienia PK dla dwóch FK, które chcesz przekształcić w INT s), a następnie utwórz te pola tutaj INT teraz i po prostu nie dodawaj FK, dopóki te inne tabele nie zostaną przeniesione do pól INT jako ich PK. Nie chcesz ponownie przebudowywać tej tabeli tylko po to, aby wprowadzić tę zmianę w polach FK.
  7. Podczas odcięcia (oczywiście w TRY / CATCH):
    1. ROZPOCZNIJ TRANSFER
    2. wykonaj ostateczną liczbę wierszy na obu tabelach, aby upewnić się, że wszystko zostało przeniesione (może chcieć sprawdzić poprawność wierszy przed wydaniem, aby upewnić się, że wyzwalacz wykonał aktualizacje i usunięcia zgodnie z oczekiwaniami)
    3. zmień nazwę bieżącej tabeli na „starą”
    4. zmień nazwę „nowej” tabeli, aby nie miała „nowej”
    5. upuść zadanie agenta SQL (lub przynajmniej wyłącz je)
    6. zmień nazwę i obiekty zależne, takie jak ograniczenia itp.
    7. POTWIERDZENIE


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sprawdź, czy plik jest pusty (SSIS)

  2. Data w IST w SQL Server

  3. Przedstawiamy wspólne wyrażenia tabelowe w SQL Server

  4. Wybieranie N-tego rekordu w zapytaniu SQL

  5. SQL do generowania XML danych tabeli