Najlepszy sposób na ponowny import dużej ilości danych przy minimalnym przestoju

11

Muszę zaimportować około 500 000 rekordów zawierających dane wyszukiwania IP (odwołanie tylko do odczytu) raz w tygodniu (tylko trzy kolumny int / bigint).

Nie chcę się martwić połączeniem danych z istniejącą tabelą, wolę wyczyścić stare i ponownie zaimportować.

Idealnie byłoby, gdyby zapytania dotyczące danych byłyby kontynuowane (nie otrzymujemy ich zbyt wiele i jest dopuszczalne, aby działały nieco wolniej podczas importowania, ale muszą być aktywne 24/7, więc uruchom to ” poza godzinami ”nie jest opcją).

Rzeczy sprawdzone do tej pory

SSIS: Utworzyłem pakiet SSIS, który obcina tabelę i importuje - uruchomienie zajmuje około 30 sekund (naprawdę zbyt długo).

Tabela temp. Importowanie do tabeli tymczasowej, obcinanie i kopiowanie zajmuje również około 30 sekund.

BCP: Import zbiorczy również jest zbyt wolny (z jakiegoś powodu jest wolniejszy niż SSIS (nawet bez indeksów do utrzymania) - Zgaduję, że ma to związek z transakcjami char-> int / bigint: /

Stół lustrzany? W tej chwili zastanawiam się nad odczytaniem tabeli przez widok, zaimportowaniem danych do tabeli lustrzanej i zmianą widoku w celu wskazania tej tabeli ... wygląda na to, że będzie to szybkie, ale wydaje się małe trochę zuchwały dla mnie.

Wydaje się, że powinien to być powszechny problem, ale nie mogę znaleźć zalecanych praktyk - wszelkie pomysły byłyby najbardziej docenione!

Dzięki

znak
źródło

Odpowiedzi:

13

Rozwiązaniem, z którego korzystałem w przeszłości (i którego wcześniej polecałem tutaj i na StackOverflow), jest utworzenie dwóch dodatkowych schematów:

CREATE SCHEMA shadow AUTHORIZATION dbo;
CREATE SCHEMA cache  AUTHORIZATION dbo;

Teraz utwórz cacheschemat naśladujący swoją tabelę w schemacie:

CREATE TABLE cache.IPLookup(...columns...);

Teraz, kiedy wykonujesz operację przełączania:

TRUNCATE TABLE cache.IPLookup;
BULK INSERT cache.IPLookup FROM ...;

-- the nice thing about the above is that it doesn't really
-- matter if it takes one minute or ten - you're not messing
-- with a table that anyone is using, so you aren't going to
-- interfere with active users.


-- this is a metadata operation so extremely fast - it will wait
-- for existing locks to be released, but won't block new locks
-- for very long at all:

BEGIN TRANSACTION;
  ALTER SCHEMA shadow TRANSFER    dbo.IPLookup;
  ALTER SCHEMA dbo    TRANSFER  cache.IPLookup;
COMMIT TRANSACTION;


-- now let's move the shadow table back over to
-- the cache schema so it's ready for next load:

ALTER SCHEMA cache TRANSFER shadow.IPLookup;
TRUNCATE TABLE cache.IPLookup; 

-- truncate is optional - I usually keep the data
-- around for debugging, but that's probably not
-- necessary in this case.

Będzie to bardziej kłopotliwe, jeśli masz klucze obce i inne zależności (ponieważ możesz je upuścić i ponownie je utworzyć), i oczywiście całkowicie unieważnia statystyki itp., Co z kolei może mieć wpływ na plany, ale jeśli najważniejsze jest uzyskanie dokładnych danych przed użytkownikami przy minimalnym zakłóceniu, może to być podejście do rozważenia.

Aaron Bertrand
źródło
Dzięki, kolejna interesująca alternatywa - myślę, że dwa ostatnie stwierdzenia nie są w porządku, powinny przenieść cień na pamięć podręczną i skrócić pamięć podręczną. Zastanawiam się, czy można również użyć synonimów?
Mark
Masz rację, pomieszałem je. Nie jestem pewien, jak dokładnie synonimy byłyby lepsze, myślę, że jest to również podejście - zobacz widok wskazujący na synonim i zmień bazowy synonim w transakcji, gdy zapełnisz drugą wersję. Osobiście uważam, że jest to trochę lepsze - kiedy odpytujesz dbo.IPLookup, wiesz, że to „bieżąca” tabela bez konieczności gonienia za widokiem i synonimem.
Aaron Bertrand
Do Twojej wiadomości blogowałem o tym bardziej szczegółowo w tym tygodniu: sqlperformance.com/2012/08/t-sql-queries/…
Aaron Bertrand