2017-05-02 3 views
0

Ich muss große Tabellen mit Millionen von Zeilen vergleichen und die Unterschiede in eine Protokolltabelle einfügen.Run groß vergleichen in Batches

Das Problem besteht darin, dass der gespeicherte Prozess wächst (LDF) und der Speicherplatz auf der Datenbank begrenzt ist.

Ich weiß, dass Commit die LDF auf die MDF schreiben wird.

Wie kann ich den folgenden Vergleich in Batches durchführen und alle hunderttausend Zeilen committen?

BEGIN TRY 
BEGIN TRANSACTION; 


      INSERT INTO dbo.CustomerLog 
        (OnlineStore , 
         PhoneNumber , 
         ChangeType 
        ) 
        SELECT 'Online Store a' , 
          AreaCode + PhoneNumber , 
          'Added' 
        FROM dbo.StoreAList a 
        WHERE NOT EXISTS (SELECT 1 
             FROM dbo.StoreAListCompare b 
             WHERE (b.AreaCode + b.PhoneNumber) = (a.AreaCode 
                   + a.PhoneNumber)); 

COMMIT TRANSACTION       
END TRY 
BEGIN CATCH 
    ROLLBACK TRANSACTION  
END CATCH; 




CREATE TABLE [dbo].[StoreAList](
    [ListID] [bigint] IDENTITY(1,1) NOT NULL, 
    [AreaCode] [char](3) NOT NULL, 
    [PhoneNumber] [char](7) NOT NULL, 
    [RecordDate] [datetime] NULL CONSTRAINT [DF_StoreAList_RecordDate] DEFAULT (getdate()) 
) ON [PRIMARY] 


CREATE TABLE [dnc].[StoreAListCompare](
    [ListID] [BIGINT] IDENTITY(1,1) NOT NULL, 
    [AreaCode] [CHAR](3) NOT NULL, 
    [PhoneNumber] [CHAR](7) NOT NULL, 
    [RecordDate] [DATETIME] NULL DEFAULT (GETDATE()) 
) ON [PRIMARY] 
+0

Beiseite: Nur neugierig auf die Leistungsänderung, wenn Sie 'StoreAList' und' StoreAListCompare' mit einem _single_ Index p indiziert haben Die Tabelle enthält sowohl "AreaCode" als auch "PhoneNumber". Ändern Sie dann die 'where', um die Felder separat zu vergleichen. – HABO

+0

Ja, sie haben Indizes, aber das Problem ist das Protokoll, nicht die Leistung –

Antwort

1

können Sie die @@rowcount Systemvariable verwenden und bis @@rowcount Treffer 0.

Notiere die hinzugefügt AND NOT EXISTS in dbo.CustomerLog ...

Ex in den Reihen der Einsatz tun:

DECLARE @BATCHSIZE INT=100000 

WHILE @BATCHSIZE>0 
BEGIN 
    BEGIN TRY 
    BEGIN TRANSACTION; 


       INSERT INTO dbo.CustomerLog 
         (OnlineStore , 
          PhoneNumber , 
          ChangeType 
         ) 
         SELECT TOP(@BATCHSIZE) 
           'Online Store a' , 
           AreaCode + PhoneNumber , 
           'Added' 
         FROM dbo.StoreAList a 
         WHERE NOT EXISTS (SELECT 1 
              FROM dbo.StoreAListCompare b 
              WHERE (b.AreaCode + b.PhoneNumber) = (a.AreaCode + a.PhoneNumber)) 
         AND NOT EXISTS (SELECT 1 
             FROM dbo.CustomerLog CL 
             WHERE 'Online Store a'=CL.OnlineStore 
             AND AreaCode + PhoneNumber=CL.PhoneNumber 
             AND 'Added'=CL.ChangeType); 

         SET @[email protected]@ROWCOUNT 

    COMMIT TRANSACTION       
    END TRY 
    BEGIN CATCH 
     ROLLBACK TRANSACTION 
     SET @BATCHSIZE=0 
    END CATCH; 
END 
Verwandte Themen