INSERT INTO vs SELECT INTO

127

Was ist der Unterschied zwischen der Verwendung

SELECT ... INTO MyTable FROM...

und

INSERT INTO MyTable (...)
SELECT ... FROM ....

?

Aus BOL [ INSERT , SELECT ... INTO ] weiß ich, dass mit SELECT ... INTO die Einfügetabelle für die Standarddateigruppe erstellt wird, sofern diese noch nicht vorhanden ist, und dass die Protokollierung für diese Anweisung von der Wiederherstellung abhängt Modell der Datenbank.

  1. Welche Aussage ist vorzuziehen?
  2. Gibt es andere Auswirkungen auf die Leistung?
  3. Was ist ein guter Anwendungsfall für SELECT ... INTO über INSERT INTO ...?

Bearbeiten: Ich habe bereits angegeben, dass ich weiß, dass SELECT INTO ... eine Tabelle erstellt, in der es nicht existiert. Ich möchte wissen, dass SQL diese Anweisung aus einem bestimmten Grund enthält. Was ist das? Tut es etwas anderes hinter den Kulissen, um Zeilen einzufügen, oder ist es nur syntaktischer Zucker über einem CREATE TABLEund INSERT INTO.

Jowenece
quelle
Ein kleiner Faktor: INSERT INTOZwei Schlüsselwörter (select & into) stehen ganz vorne, die die Welt wissen lassen, dass dies keine gewöhnliche SQL-Anweisung ist, während sie SELECT ... INTOzumindest wie eine gewöhnliche SQL-Anweisung aussieht. Ein kleiner Grund, den ersteren zu bevorzugen.
Martin F

Antworten:

121
  1. Sie machen verschiedene Dinge. Verwenden Sie diese Option, INSERTwenn die Tabelle vorhanden ist. Verwenden Sie, SELECT INTOwenn dies nicht der Fall ist.

  2. Ja. INSERTohne Tabellenhinweise wird normalerweise protokolliert. SELECT INTOwird minimal protokolliert, vorausgesetzt, dass die richtigen Ablaufverfolgungsflags gesetzt sind.

  3. Nach meiner Erfahrung SELECT INTOwird es am häufigsten mit Zwischendatensätzen wie #tempTabellen oder zum Kopieren einer gesamten Tabelle wie für eine Sicherung verwendet. INSERT INTOwird verwendet, wenn Sie in eine vorhandene Tabelle mit bekannter Struktur einfügen.

BEARBEITEN

Um Ihre Bearbeitung zu adressieren, machen sie verschiedene Dinge. Wenn Sie eine Tabelle erstellen und die Struktur definieren möchten, verwenden Sie CREATE TABLEund INSERT. Beispiel für ein Problem, das erstellt werden kann: Sie haben eine kleine Tabelle mit einem Varchar-Feld. Die größte Zeichenfolge in Ihrer Tabelle ist jetzt 12 Byte. Ihr realer Datensatz benötigt bis zu 200 Bytes. Wenn Sie SELECT INTOaus Ihrer kleinen Tabelle eine neue erstellen, INSERTschlägt die spätere mit einem Kürzungsfehler fehl, da Ihre Felder zu klein sind.

JNK
quelle
4
Meine zwei Cent, ich denke, Fehler einzuführen ist eine gute Sache. Ich möchte wissen, ob meine Daten nicht meinem erwarteten Datenformat / meiner erwarteten Datengröße entsprechen. Ich versuche immer, meine Tabelle mit zu definieren, CREATE TABLEund dann INSERT INTOist es auch einfacher, die SELECTAnweisung selbst zu testen , ohne die Einfügung auszuführen.
Doug Chamberlain
1
@ Doug - ich stimme zu. Ich verwende fast ausschließlich SELECT INTO, um eine temporäre Tabelle zu erstellen oder eine schnelle Sicherung einer vorhandenen Tabelle zu erstellen, mit der ich Affen spielen werde.
JNK
1
@JNK - Aus BOL erstellt SELECT INTO eine Tabelle mit einer Struktur, die auf den Datentypen der Spalten in der Auswahlliste basiert. In Ihrem Beispiel könnten Sie also die Situation korrigieren, indem Sie den Varchar explizit auf eine Größe umwandeln, die ausreicht. Richtig?
Jowenece
2
@Jowenece - ja das erwarte ich. Wenn ich in diese Schwierigkeiten gerate, werde ich CREATEtrotzdem eine Aussage machen.
JNK
23
  1. Welche Aussage ist vorzuziehen? Kommt darauf an, was du tust.

  2. Gibt es andere Auswirkungen auf die Leistung? Wenn es sich bei der Tabelle um eine permanente Tabelle handelt, können Sie zum Zeitpunkt der Tabellenerstellung Indizes erstellen, was sich sowohl negativ als auch positiv auf die Leistung auswirkt. Durch Auswahl von werden keine Indizes neu erstellt, die für aktuelle Tabellen vorhanden sind. Daher kann die spätere Verwendung der Tabelle langsamer sein als erforderlich.

  3. Was ist ein guter Anwendungsfall für SELECT ... INTO über INSERT INTO ...? Die Auswahl in wird verwendet, wenn Sie die Tabellenstruktur möglicherweise nicht im Voraus kennen. Es ist schneller zu schreiben als eine Tabelle und eine Einfügeanweisung zu erstellen, daher wird es manchmal verwendet, um die Entwicklung zu beschleunigen. Es ist oft schneller zu verwenden, wenn Sie eine schnelle temporäre Tabelle zum Testen von Dingen oder eine Sicherungstabelle einer bestimmten Abfrage erstellen (möglicherweise Datensätze, die Sie löschen möchten). Es sollte selten vorkommen, dass es in Produktionscode verwendet wird, der mehrmals ausgeführt wird (mit Ausnahme von temporären Tabellen), da es fehlschlägt, wenn die Tabelle bereits vorhanden war.

Es wird manchmal unangemessen von Menschen verwendet, die nicht wissen, was sie tun. Und sie können infolgedessen Chaos in der Datenbank verursachen. Ich halte es für unangemessen, SELECT INTO für etwas anderes als eine Wegwerftabelle zu verwenden (eine temporäre Sicherung, eine temporäre Tabelle, die am Ende des gespeicherten Prozesses verschwindet usw.). Permanente Tabellen erfordern echte Überlegungen zu ihrem Design. Mit SELECT INTO können Sie leicht vermeiden, an etwas zu denken, das so grundlegend ist wie die Spalten und Datentypen.

Im Allgemeinen bevorzuge ich die Verwendung der Anweisung create table und insert - Sie haben mehr Steuerelemente und es ist besser für wiederholbare Prozesse. Wenn es sich bei der Tabelle um eine permanente Tabelle handelt, sollte sie aus einem separaten Skript zum Erstellen einer Tabelle (das sich in der Quellcodeverwaltung befindet) erstellt werden, da das Erstellen permanenter Objekte im Allgemeinen im Code keine Einfügungen / Löschungen / Aktualisierungen oder Auswahlen aus a sein sollte Tabelle. Objektänderungen sollten getrennt von Datenänderungen behandelt werden, da Objekte Auswirkungen haben, die über die Anforderungen eines bestimmten Einfügens / Aktualisierens / Auswählens / Löschens hinausgehen. Sie müssen die besten Datentypen berücksichtigen, über FK-Einschränkungen, PKs und andere Einschränkungen nachdenken, Prüfanforderungen berücksichtigen, über die Indizierung nachdenken usw.

HLGEM
quelle
5

Der Hauptunterschied besteht darin, dass SELECT INTO MyTable eine neue Tabelle mit dem Namen MyTable mit den Ergebnissen erstellt, während INSERT INTO erfordert, dass MyTable bereits vorhanden ist.

Sie würden SELECT INTO nur verwenden, wenn die Tabelle nicht vorhanden war und Sie sie basierend auf den Ergebnissen Ihrer Abfrage erstellen wollten. Insofern sind diese beiden Aussagen wirklich nicht vergleichbar. Sie machen sehr unterschiedliche Dinge.

Im Allgemeinen wird SELECT INTO häufiger für einmalige Aufgaben verwendet, während INSERT INTO regelmäßig zum Hinzufügen von Zeilen zu Tabellen verwendet wird.

BEARBEITEN:
Während Sie CREATE TABLE und INSERT INTO verwenden können, um das zu erreichen, was SELECT INTO tut, müssen Sie mit SELECT INTO die Tabellendefinition nicht vorher kennen. SELECT INTO ist wahrscheinlich in SQL enthalten, da es Aufgaben wie Ad-hoc-Berichte oder das Kopieren von Tabellen erheblich vereinfacht.

rsbarro
quelle
CREATE TABLE und SELECT INTO sind ziemlich dasselbe (brauchen INSERT INTO nicht als Ergänzung, um das zu erreichen, was SELECT INTO tut) und SELECT INTO wird meiner Meinung nach nicht empfohlen. Siehe dba.stackexchange.com/questions/156105/… .
Rick
4

Jede Anweisung hat einen eigenen Anwendungsfall. Sie sind nicht austauschbar.

SELECT...INTO MyTable...schafft eine neue, MyTablewo es vorher keine gab.

INSERT INTO MyTable...SELECT...wird verwendet, wenn MyTablebereits vorhanden.

Joe Stefanelli
quelle
4
Sie haben keine meiner Fragen beantwortet und ich habe Ihre Antwort bereits angegeben.
Jowenece
5
Die Antworten auf Ihre Fragen sind impliziert. Um es klarer zu machen, gibt es keine "vorzuziehende" Aussage, da jede einen eigenen Anwendungsfall hat. Die Aussagen sind nicht austauschbar. Verwenden Sie die erste Version, wenn Sie eine neue Tabelle erstellen möchten, die nicht vorhanden ist. Verwenden Sie die zweite Version, wenn die Tabelle bereits vorhanden ist.
Joe Stefanelli
2
Warum sollte ich das tun wollen, anstatt eine temporäre Tabelle zu erstellen und dann in diese einzufügen? Gibt es einen Vorteil?
Jowenece
4

Tatsächlich SELECT ... INTO erstellt nicht nur die Tabelle, sondern schlägt auch fehl, wenn sie bereits vorhanden ist. Sie würden sie also grundsätzlich nur verwenden, wenn die Tabelle, in die Sie einfügen, nicht vorhanden ist.

In Bezug auf Ihre EDIT:

Ich persönlich benutze hauptsächlich SELECT ... INTO, wenn ich eine temporäre Tabelle erstelle. Das ist für mich die Hauptverwendung. Ich verwende es jedoch auch, wenn ich neue Tabellen mit vielen Spalten mit ähnlichen Strukturen wie andere Tabellen erstelle und es dann bearbeite, um Zeit zu sparen.

AJC
quelle
1
Ich sehe hauptsächlich Verwendungen von SELECT..INTO auch für temporäre Tabellen, aber gibt es einen Grund, dies der Erstellung einer temporären Tabelle mit einer CREATE TABLE-Anweisung vorzuziehen? ZB - Leistungsgewinn?
Jowenece
3
@jowenece Ich denke hauptsächlich der Einfachheit halber ... Sagen Sie auch, Sie haben eine dynamische Abfrage. Wenn Sie die Struktur nicht kennen, können Sie die Tabelle nicht vorher erstellen, und es ist viel einfacher, SELECT ... INTO zu verwenden, als eine Tabelle dinamisch zu erstellen.
AJC
3

SELECT INTO wird normalerweise verwendet, um temporäre Tabellen zu generieren oder eine andere Tabelle (Daten und / oder Struktur) zu kopieren.

Im täglichen Code verwenden Sie INSERT, da Ihre Tabellen bereits zum Lesen, UPDATEd, DELETEd, JOINed usw. vorhanden sein sollten. Hinweis: Das Schlüsselwort INTO ist bei INSERT optional

Das heißt, Anwendungen erstellen und löschen normalerweise keine Tabellen im Rahmen des normalen Betriebs, es sei denn, es handelt sich um eine temporäre Tabelle für einen bestimmten Bereich mit eingeschränkter und spezifischer Verwendung.

Eine von SELECT INTO erstellte Tabelle hat im Gegensatz zu einer realen, persistierten, bereits vorhandenen Tabelle keine Schlüssel, Indizes oder Einschränkungen

Die 2 sind nicht direkt vergleichbar, da sie fast keine Überlappung in der Verwendung haben

gbn
quelle
2

Ich möchte nur den zweiten Punkt der Frage behandeln, der sich auf die Leistung bezieht, weil kein anderer Körper dies behandelt hat. Die Auswahl von Into ist bei Tabellen mit großen Datenmengen viel schneller als das Einfügen in. Ich bevorzuge die Auswahl, wenn ich eine sehr große Tabelle lesen muss. Das Einfügen in eine Tabelle mit 10 Millionen Zeilen kann Stunden dauern, während das Auswählen in in Minuten erfolgt. Wenn Sie Indizes für neue Tabellen verlieren, können Sie die Indizes per Abfrage neu erstellen und im Vergleich zu noch viel mehr Zeit sparen einfügen in.

Niraj
quelle
Das stimmt, aber das liegt hauptsächlich daran, dass SQL Server weiß, dass es keine Konflikte für die Zieltabelle gibt. Die Leistung für insert into #temp with(tablock) select * from ..ist ungefähr die gleiche wie die Leistung fürselect * into #temp from ...
Brian
1

Wählen Sie in, um eine neue Tabelle für Sie zu erstellen, und fügen Sie dann Datensätze aus der Quelltabelle ein. Die neu erstellte Tabelle hat dieselbe Struktur wie die Quelltabelle. Wenn Sie versuchen, select in für eine vorhandene Tabelle zu verwenden, wird ein Fehler ausgegeben, da versucht wird, eine neue Tabelle mit demselben Namen zu erstellen. Zum Einfügen in muss die Tabelle in Ihrer Datenbank vorhanden sein, bevor Sie Zeilen einfügen.

Satish Vishwakarma
quelle
1

Der einfache Unterschied zwischen Auswählen in und Einfügen in ist: -> Auswählen in benötigt keine vorhandene Tabelle. Wenn Sie Daten aus Tabelle A kopieren möchten, geben Sie einfach Select * INTO [Tabellenname] aus A ein. Hier kann Tabellenname eine vorhandene Tabelle sein, oder es wird eine neue Tabelle erstellt, die dieselbe Struktur wie Tabelle A hat.

-> Einfügen in benötigt vorhandene Tabelle.INSERT INTO [Tabellenname] SELECT * FROM A;. Hier ist Tabellenname eine vorhandene Tabelle.

Die Auswahl von Into ist normalerweise beliebter, um Daten zu kopieren, insbesondere Sicherungsdaten.

Sie können gemäß Ihren Anforderungen verwenden, es ist völlig Entwicklerwahl, die in seinem Szenario verwendet werden sollte.

Leistungsmäßig ist Insert INTO schnell.

Verweise :

https://www.w3schools.com/sql/sql_insert_into_select.asp https://www.w3schools.com/sql/sql_select_into.asp

Aditya Parmar
quelle
-2

Die Auswahl für große Datenmengen ist möglicherweise nur für einen einzelnen Benutzer geeignet, der eine einzige Verbindung zur Datenbank verwendet, die eine Massenoperationsaufgabe ausführt. Ich empfehle nicht zu verwenden

SELECT * INTO table

Dadurch wird eine große Transaktion erstellt und eine Schemasperre zum Erstellen des Objekts erstellt. Dadurch wird verhindert, dass andere Benutzer Objekte erstellen oder auf Systemobjekte zugreifen, bis der SELECT INTOVorgang abgeschlossen ist.

Als Proof of Concept öffnen Sie 2 Sitzungen, versuchen Sie in der ersten Sitzung zu verwenden

select into temp table from a huge table 

und im zweiten Abschnitt versuchen

create a temp table 

Überprüfen Sie die Sperren, das Blockieren und die Dauer der zweiten Sitzung, um ein temporäres Tabellenobjekt zu erstellen. Meine Empfehlung ist es immer eine gute Praxis, eine Anweisung zu erstellen und einzufügen und bei Bedarf für eine minimale Protokollierung das Trace-Flag 610 zu verwenden.

user6802184
quelle