none
MERGE INTO extrem langsam RRS feed

  • Frage

  • Hallo Gemeinde,

    ich habe in einer Stored Procedure Merges auf folgende Art imlementiert:

    MERGE INTO [d].[dd].[Defects] AS target
    USING (SELECT *
       FROM [linked_server].[d].[dd].[Defects]
       WHERE Segment BETWEEN @FirstSegment
                         AND @LastSegment)
          AS source
          ON source.Id = target.Id
          WHEN NOT MATCHED BY TARGET THEN
             INSERT (f1, f2, f3, f4, f5, f6)
             VALUES (source.f1, source.f2,source.f3, 
                       source.f4, source.f5, source.f6);

    im Sourcetable werden etwa 30000 Datensätze selektiert. Source und Destinaton Table haben ca 2.5 Milliarden Einträge. Die Aktion dauert etwa 10 Minuten je MERGE. Da die Dauer immer weiter gestiegen ist je größer die Targettabelle geworden ist hab ich ein paar Untersuchungen gemacht. Egal wie viele Datensätze ich selectiere die Dauer bleibt in etwa gleich was zu der dann zutreffenden Vermutung geführt hat, das MERGE INTO offensichtlich einen full outer join der Tabellen aufbaut um an die NOT MATCHED Info zu gelangen. Zum Testen habe ich mal einen select/insert mit gleichen Daten versucht der bei 8 Sekunden liegt. Wie von Microsoft verlangt haben die source.Id und target.Id einen clustered index (sind sogar Primärschlüssel).

    Ich kann mir einfach nicht vorstellen, das der execution plan für das Szenario nichts besseres ausspucken kann.

    Muss ich jetzt wieder auf NOT EXIST/SELECT/INSERT zurückgreifen oder habt ihr noch einen Tip wie ich das ganze beschleunigen kann? Irgendwas mache ich doch falsch?

    Gruß
    Wolfgang


    Dienstag, 26. August 2014 14:08

Alle Antworten

  • Da die Dauer immer weiter gestiegen ist je größer die Targettabelle geworden ist hab ich ein paar Untersuchungen gemacht. Egal wie viele Datensätze ich selectiere die Dauer bleibt in etwa gleich was zu der dann zutreffenden Vermutung geführt hat, das MERGE INTO offensichtlich einen full outer join der Tabellen aufbaut um an die NOT MATCHED Info zu gelangen.

    das ist leider so.

    Somit musst Du versuchen die Groesse der Targettabelle im Merge-Statement zu beschraenken.

    eine Moeglichkeit ist, die Targettabelle mittels CTE zu definieren und innerhalb der CTE die Anzahl Records so weit als moeglich einzuschraenken.

    Ueberdies wuerde ich ausprobieren ob nicht die Records vom LinkedServer zuerst in eine temporaere Tabelle geladen werden sollten und diese dann referenziert wird - abhaengig von Art des LinkedServer koennte dies ein Geschwindigkeitsunterschied ergeben.

    hier noch ein Links zum Tuning von Merge Statement: Optimizing MERGE Statement Performance


    Please use Mark as Answer if my post solved your problem and use Vote As Helpful if a post was useful.



    Dienstag, 26. August 2014 14:26
  • Hallo Daniel,

    danke für Deine Antwort.
    Ich werde mir das mit der CTE mal ansehen.

    Gruß
    Wolfgang

    Mittwoch, 27. August 2014 05:17