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

Jak zoptymalizować działanie Upsert (aktualizacja i wstawianie) w pakiecie SSIS?

Przykładowy pakiet korzystający z SSIS 2008 R2, który wstawia lub aktualizuje za pomocą operacji wsadowej:

Oto przykładowy pakiet napisany w SSIS 2008 R2 który ilustruje, jak wykonać wstawianie, aktualizować między dwiema bazami danych za pomocą operacji wsadowych.

  • Korzystanie z OLE DB Command spowolni operacje aktualizacji Twojego pakietu, ponieważ nie wykonywać operacje wsadowe. Każdy wiersz jest aktualizowany indywidualnie.

Przykład wykorzystuje dwie bazy danych, a mianowicie Source i Destination . W moim przykładzie obie bazy danych znajdują się na serwerze, ale logika nadal może być stosowana do baz danych znajdujących się na różnych serwerach i lokalizacjach.

Utworzyłem tabelę o nazwie dbo.SourceTable w mojej źródłowej bazie danych Source .

CREATE TABLE [dbo].[SourceTable](
    [RowNumber] [bigint] NOT NULL,
    [CreatedOn] [datetime] NOT NULL,
    [ModifiedOn] [datetime] NOT NULL,
    [IsActive] [bit] NULL
)

Utworzono również dwie tabele o nazwie dbo.DestinationTable i dbo.StagingTable w mojej docelowej bazie danych Destination .

CREATE TABLE [dbo].[DestinationTable](
    [RowNumber] [bigint] NOT NULL,
    [CreatedOn] [datetime] NOT NULL,
    [ModifiedOn] [datetime] NOT NULL
) 
GO

CREATE TABLE [dbo].[StagingTable](
    [RowNumber] [bigint] NOT NULL,
    [CreatedOn] [datetime] NOT NULL,
    [ModifiedOn] [datetime] NOT NULL
) 
GO

Wstawiono około 1,4 miliona wierszy w tabeli dbo.SourceTable z unikalnymi wartościami w RowNumber kolumna. Tabele dbo.DestinationTable i dbo.StagingTable były puste na początku. Wszystkie wiersze w tabeli dbo.SourceTable mieć flagę IsActive ustawione na fałsz.

Utworzono pakiet SSIS z dwoma menedżerami połączeń OLE DB, z których każdy łączy się z Source i Destination bazy danych. Zaprojektowano przepływ sterowania, jak pokazano poniżej:

  • Pierwsze Execute SQL Task wykonuje instrukcję TRUNCATE TABLE dbo.StagingTable względem docelowej bazy danych, aby obciąć tabele pomostowe.

  • Następna sekcja wyjaśnia, jak Data Flow Task jest skonfigurowany.

  • Drugie Execute SQL Task wykonuje podaną poniżej instrukcję SQL, która aktualizuje dane w dbo.DestinationTable korzystając z danych dostępnych w dbo.StagingTable , zakładając, że istnieje unikalny klucz pasujący między tymi dwiema tabelami. W tym przypadku unikalnym kluczem jest kolumna RowNumber .

Skrypt do aktualizacji:

UPDATE      D 
SET         D.CreatedOn = S.CreatedOn
        ,   D.ModifiedOn = S.ModifiedOn 
FROM        dbo.DestinationTable D 
INNER JOIN  dbo.StagingTable S 
ON          D.RowNumber = S.RowNumber

Zaprojektowałem zadanie przepływu danych, jak pokazano poniżej.

  • OLE DB Source odczytuje dane z dbo.SourceTable za pomocą polecenia SQL SELECT RowNumber,CreatedOn, ModifiedOn FROM Source.dbo.SourceTable WHERE IsActive = 1

  • Lookup transformation służy do sprawdzenia, czy wartość RowNumber już istnieje w tabeli dbo.DestinationTable

  • Jeśli rekord nie istnieje, zostanie przekierowany do OLE DB Destination nazwany jako Insert into destination table , który wstawia wiersz do dbo.DestinationTable

  • Jeśli rekord istnieje , zostanie przekierowany do OLE DB Destination nazwany jako Insert into staging table , który wstawia wiersz do dbo.StagingTable . Te dane w tabeli pomostowej zostaną użyte w drugim `Wykonaj zadanie SQL w celu wykonania zbiorczej aktualizacji.

Aby aktywować kilka dodatkowych wierszy dla źródła OLE DB, uruchomiłem poniższe zapytanie, aby aktywować niektóre rekordy

UPDATE  dbo.SourceTable 
SET     IsActive = 1 
WHERE   (RowNumber % 9 = 1) 
OR      (RowNumber % 9 = 2)

Pierwsze wykonanie pakietu wyglądało jak pokazano poniżej. Wszystkie wiersze zostały skierowane do tabeli docelowej, ponieważ była pusta. Wykonanie pakietu na moim komputerze zajęło około 3 seconds .

Uruchom ponownie zapytanie dotyczące liczby wierszy, aby znaleźć liczbę wierszy we wszystkich trzech tabelach.

Aby aktywować kilka dodatkowych wierszy dla źródła OLE DB, uruchomiłem poniższe zapytanie, aby aktywować niektóre rekordy

UPDATE  dbo.SourceTable 
SET     IsActive = 1 
WHERE   (RowNumber % 9 = 3) 
OR      (RowNumber % 9 = 5) 
OR      (RowNumber % 9 = 6) 
OR      (RowNumber % 9 = 7)

Drugie wykonanie pakietu wyglądało jak pokazano poniżej. 314,268 rows które zostały wcześniej wstawione podczas pierwszego wykonania, zostały przekierowane do tabeli pomostowej. 628,766 new rows zostały bezpośrednio wstawione do tabeli docelowej. Wykonanie pakietu na moim komputerze zajęło około 12 seconds . 314,268 rows w tabeli docelowej zostały zaktualizowane w drugim wykonaniu zadania SQL danymi przy użyciu tabeli pomostowej.

Uruchom ponownie zapytanie dotyczące liczby wierszy, aby znaleźć liczbę wierszy we wszystkich trzech tabelach.

Mam nadzieję, że to podsuwa Ci pomysł na wdrożenie Twojego rozwiązania.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dziesiętny przekazany niepoprawnie z C# do SQL Server za pomocą TableAdapters

  2. Czy istnieje sposób na wykonanie innego zapytania w ramach zapytania wstawiającego?

  3. SQL — konwersja typu danych varchar na typ danych data/godzina skutkowała wartością spoza zakresu

  4. Utwórz/Dołącz tabelę z sumą wartości pogrupowanych w różne kategorie

  5. Przedstawiamy nową funkcję — replikację Spotlight w chmurze