Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie optimiere ich den Upsert-Vorgang (Aktualisieren und Einfügen) innerhalb des SSIS-Pakets?

Beispielpaket mit SSIS 2008 R2, das mithilfe des Stapelvorgangs einfügt oder aktualisiert:

Hier ist ein Beispielpaket, das in SSIS 2008 R2 geschrieben wurde das veranschaulicht, wie Einfügungen und Aktualisierungen zwischen zwei Datenbanken mithilfe von Stapeloperationen durchgeführt werden.

  • Mit OLE DB Command verlangsamt die Aktualisierungsvorgänge Ihres Pakets, da dies nicht der Fall ist Batch-Operationen durchführen. Jede Zeile wird einzeln aktualisiert.

Das Beispiel verwendet zwei Datenbanken, nämlich Source und Destination . In meinem Beispiel befinden sich beide Datenbanken auf dem Server, aber die Logik kann weiterhin auf Datenbanken angewendet werden, die sich auf unterschiedlichen Servern und Standorten befinden.

Ich habe eine Tabelle namens dbo.SourceTable erstellt in meiner Quelldatenbank Source .

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

Außerdem wurden zwei Tabellen namens dbo.DestinationTable erstellt und dbo.StagingTable in meiner Zieldatenbank 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

Etwa 1,4 Millionen Zeilen in die Tabelle dbo.SourceTable eingefügt mit eindeutigen Werten in RowNumber Säule. Die Tabellen dbo.DestinationTable und dbo.StagingTable waren zunächst leer. Alle Zeilen in der Tabelle dbo.SourceTable haben das Flag IsActive auf false setzen.

Erstellt ein SSIS-Paket mit zwei OLE DB-Verbindungs-Managern, die jeweils eine Verbindung zu Source herstellen und Destination Datenbanken. Gestalten Sie den Kontrollfluss wie unten gezeigt:

  • Zuerst Execute SQL Task führt die Anweisung TRUNCATE TABLE dbo.StagingTable aus gegen die Zieldatenbank, um die Staging-Tabellen zu kürzen.

  • Der nächste Abschnitt erklärt, wie die Data Flow Task konfiguriert ist.

  • Zweite Execute SQL Task führt die unten angegebene SQL-Anweisung aus, die Daten in dbo.DestinationTable aktualisiert unter Verwendung der in dbo.StagingTable verfügbaren Daten , vorausgesetzt, es gibt einen eindeutigen Schlüssel, der zwischen diesen beiden Tabellen übereinstimmt. Der eindeutige Schlüssel ist in diesem Fall die Spalte RowNumber .

Zu aktualisierendes Skript:

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

Ich habe die Datenflussaufgabe wie unten gezeigt entworfen.

  • OLE DB Source liest Daten aus dbo.SourceTable mit dem SQL-Befehl SELECT RowNumber,CreatedOn, ModifiedOn FROM Source.dbo.SourceTable WHERE IsActive = 1

  • Lookup transformation wird verwendet, um zu prüfen, ob der RowNumber-Wert bereits in der Tabelle dbo.DestinationTable existiert

  • Wenn der Datensatz nicht vorhanden ist, wird sie an das OLE DB Destination umgeleitet benannt als Insert into destination table , wodurch die Zeile in dbo.DestinationTable eingefügt wird

  • Wenn der Datensatz vorhanden ist , wird es zum OLE DB Destination umgeleitet benannt als Insert into staging table , wodurch die Zeile in dbo.StagingTable eingefügt wird . Diese Daten in der Staging-Tabelle werden im zweiten `Execute SQL Task to perform batch update.

    verwendet

Um einige weitere Zeilen für die OLE DB-Quelle zu aktivieren, habe ich die folgende Abfrage ausgeführt, um einige Datensätze zu aktivieren

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

Die erste Ausführung des Pakets sah wie unten gezeigt aus. Alle Zeilen wurden an die Zieltabelle weitergeleitet, da sie leer war. Die Ausführung des Pakets auf meinem Rechner dauerte etwa 3 seconds .

Führen Sie die Zeilenanzahlabfrage erneut aus, um die Zeilenanzahl in allen drei Tabellen zu finden.

Um einige weitere Zeilen für die OLE DB-Quelle zu aktivieren, habe ich die folgende Abfrage ausgeführt, um einige Datensätze zu aktivieren

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

Die zweite Ausführung des Pakets sah wie unten gezeigt aus. 314,268 rows die zuvor bei der ersten Ausführung eingefügt wurden, wurden in die Staging-Tabelle umgeleitet. 628,766 new rows wurden direkt in die Zieltabelle eingefügt. Die Ausführung des Pakets auf meinem Rechner dauerte etwa 12 seconds . 314,268 rows in der Zieltabelle wurden im zweiten Task „SQL ausführen“ mit den Daten aktualisiert, die die Staging-Tabelle verwenden.

Führen Sie die Zeilenanzahlabfrage erneut aus, um die Zeilenanzahl in allen drei Tabellen zu finden.

Ich hoffe, das gibt Ihnen eine Idee zur Umsetzung Ihrer Lösung.