Muszę zaktualizować 100 milionów rekordów w jednej tabeli, w efekcie normalizując tabelę, zastępując wartość varchar kolumny zwykłym identyfikatorem. (Mówię „zastępuję”, ale tak naprawdę piszę identyfikator w innej kolumnie).
Staram się znormalizować zestaw danych. Dane jeszcze nie znormalizowane nie mają indeksowania. Myślałem, że nie będę budował indeksów na wartościach surowych, czekając, zamiast indeksować klucze obce, które zastąpią wartości varchar wartościami tinyint po zakończeniu aktualizacji.
UPDATE A
SET A.AutoClassID = B.AutoClassID
FROM AutoDataImportStaging.dbo.Automobile as A
JOIN AutoData.dbo.AutoClass as B on (A.AutoClassName = B.AutoClassName)
tło
- za pomocą MSSQL 2008 R2 na Server 2008 R2
- serwer ma 8 GB pamięci RAM
- serwer ma jeden RAID10, 7200 RPM SATA (nie wspaniale, wiem, w produkcji to będzie tylko czytać dane, a nie zapisywać dane; plus niedawny brak HD spowodował, że było to konieczne)
- Serwer ma podwójny czterordzeniowy procesor Xeon
- maszyna nie robi nic innego (obecnie poświęcony programowaniu, tylko ten proces)
- proste logowanie włączone (? - ale czy nadal się loguje, aby móc przywrócić?)
- zwróć uwagę, że zapytanie odwołuje się do dwóch różnych baz danych dla tego, co jest warte
- „szerokość” rekordu w aktualizowanej tabeli wynosi 455 bajtów
Zasoby podczas wykonywania
- fizyczna pamięć RAM jest maksymalna
- dysk we / wy jest maksymalny
- Procesor prawie nic nie robi (dławik to We / Wy)
- czas działania wyniósł 14 godzin i wciąż rośnie!
Podejrzewam kilka rzeczy, takich jak potrzebuję indeksu na surowych danych, nawet jeśli po aktualizacji normalizacji będę upuszczał kolumnę (AutoClassName). Zastanawiam się również, czy powinienem po prostu zapętlać jeden rekord na raz zamiast JOIN, co wydawało się śmieszne w momencie, gdy to zaczynałem, ale teraz wydaje się, że byłoby szybciej.
Jak powinienem zmienić metodologię pozostałych aktualizacji normalizacyjnych (podobnych do tej) szybciej?
TOP
klauzuli. To byłoby moje podejście.