Warum "Wählen Sie * in Ziel aus Sourcetable aus" ist schneller als "In Ziel einfügen auswählen * aus Sourcetable"

9

Dieser Titel ist die Frage. Ich bin gespannt auf die Antwort. Jemand hat es erzählt

select in ist minimal in der Simple Recovery Model-Datenbank angemeldet ... Ich bin überhaupt nicht darauf gekommen.

Auszug aus Microsoft:

Der Umfang der Protokollierung für SELECT ... INTO hängt vom für die Datenbank gültigen Wiederherstellungsmodell ab. Unter dem einfachen Wiederherstellungsmodell oder dem massenprotokollierten Wiederherstellungsmodell werden Massenvorgänge nur minimal protokolliert. Bei minimaler Protokollierung kann die Verwendung der Anweisung SELECT… INTO effizienter sein als das Erstellen einer Tabelle und das anschließende Auffüllen der Tabelle mit einer INSERT-Anweisung

Hilfe suchen

Vielen Dank


quelle
Welche Datenbank verwenden Sie? Welche Strukturen haben die Tabellen? Wie haben Sie gemessen, dass einer schneller ist als der andere?
Ich wäre überrascht, wenn es bei einem gut geschriebenen DBMS einen Unterschied gäbe.
Datenbank: SQL Server 20005 ... und ich habe das gehört ... auch wenn ich nicht 100% sicher bin ... Ich suche nach dem, was andere
Es wurde ein Link gefunden, der bestätigt, dass er SELECT INTOnur minimal protokolliert werden kann, wenn die vollständige Wiederherstellung nicht verwendet wird.
Damien_The_Unbeliever

Antworten:

10

Ein paar Ideen / Theorien:

SELECT INTO ... lässt das RDBMS die Sortierreihenfolge basierend auf der Reihenfolge Ihrer ursprünglichen Tabelle bestimmen. Wenn Sie in eine vorhandene Tabelle einfügen, ist möglicherweise eine Sortierung erforderlich, um mit einem oder mehreren gruppierten oder nicht gruppierten Indizes übereinzustimmen.

Keine Indizes - Wenn Sie SELECT INTO...vom RDBMS sicher wissen, dass keine Indizes vorhanden sind, die aktualisiert werden müssen.

Keine Konflikte - Da die Tabelle, in die Sie einfügen, nicht vorhanden ist, muss sich SQL Server nicht um das Sperren auf Zeilenebene oder die Behandlung von Konflikten kümmern. Nichts anderes kann auf die von Ihnen erstellte Tabelle verweisen, da sie nicht vorhanden ist.

Abgesehen davon gibt es andere Möglichkeiten, sehr schnell in eine Tabelle einzufügen.

  • Stellen Sie sicher, dass Ihre Clustered-Indexschlüssel nach Möglichkeit übereinstimmen. Dies bedeutet, dass keine direkte Sortierung erfolgt

  • Deaktivieren Sie alle nicht gruppierten Indizes. Selbsterklärend.

  • Setzen Sie den Wiederherstellungsmodus auf einfach und verfolgen Sie das Flag 610 auf ON. Verwenden Sie den TABLOCKHinweis in Ihrer Zieltabelle und den NOLOCKHinweis in Ihrer Quelltabelle.

Angenommen, Tablea und Tableb haben denselben Clustered-Index:

INSERT INTO TableB WITH (TABLOCK)
SELECT <Columns>
FROM TableA WITH (NOLOCK)

Nach meiner Erfahrung ist dies schneller als die Verwendung SELECT INTO...und anschließende Erstellung des Clustered-Index. Bitte beachten Sie, dass dies auch für eine Tabelle funktionieren kann, in der bereits Daten enthalten sind. Dies ist ein viel nützlicheres Szenario.

BEARBEITEN:

Hier ist ein fantastisch detailliertes Whitepaper von MS zur Leistung beim Laden von Daten in SQL Server 2008.

JNK
quelle
3
Sehr gründliche Antwort JNK. Bei korrekter Implementierung und nicht vollständigem Wiederherstellungsmodell kann eine einfache SSIS-Datenflussaufgabe schneller sein als beide. Warum? In beiden oben genannten Fällen wird eine exklusive Sperre ausgegeben (Lesen ist Multithread, Schreiben ist jedoch ein einzelner Thread). Solange mit dem Zieladapter eine Tabellensperre verwendet wird, verwendet SSIS eine Massenaktualisierungssperre (sowohl Lesen als auch Schreiben sind Multithreads).
Brian