INSERT INTO vs SELECT INTO


127

Qual'è la differenza tra using

SELECT ... INTO MyTable FROM...

e

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

?

Da BOL [ INSERISCI , SELEZIONA ... INTO ], so che l'uso di SELEZIONA ... INTO creerà la tabella di inserimento nel gruppo di file predefinito se non esiste già e che la registrazione per questa istruzione dipende dal recupero modello del database.

  1. Quale affermazione è preferibile?
  2. Ci sono altre implicazioni sulle prestazioni?
  3. Qual è un buon caso d'uso per SELECT ... INTO su INSERT INTO ...?

Modifica: ho già affermato che so che SELECT INTO ... crea una tabella dove non esiste. Quello che voglio sapere è che SQL include questa affermazione per un motivo, che cos'è? Sta facendo qualcosa di diverso dietro le quinte per l'inserimento di righe o è solo zucchero sintattico in cima a un CREATE TABLEe INSERT INTO.


Un piccolo fattore: INSERT INTOha due parole chiave (seleziona e in) in primo piano che indicano al mondo che questa non è una normale istruzione SQL, mentre SELECT ... INTOalmeno inizia a sembrare una normale istruzione SQL. Un piccolo motivo per favorire il primo.
Martin F,

Risposte:


122
  1. Fanno cose diverse. Utilizzare INSERTquando esiste la tabella. Utilizzare SELECT INTOquando non lo fa.

  2. Sì. INSERTsenza suggerimenti per la tabella viene normalmente registrato. SELECT INTOviene minimamente registrato presupponendo che siano impostati flag di traccia corretti.

  3. Nella mia esperienza, il SELECT INTOpiù delle volte viene utilizzato con set di dati intermedi, come #temptabelle, o per copiare un'intera tabella come per un backup. INSERT INTOviene utilizzato quando si inserisce in una tabella esistente con una struttura nota.

MODIFICARE

Per affrontare la tua modifica, fanno cose diverse. Se stai creando una tabella e vuoi definire la struttura usa CREATE TABLEe INSERT. Esempio di un problema che può essere creato: hai una piccola tabella con un campo varchar. La stringa più grande nella tabella ora è di 12 byte. Il set di dati reali richiederà fino a 200 byte. Se lo fai SELECT INTOdalla tua piccola tabella per crearne una nuova, la successiva INSERTnon riuscirà con un errore di troncamento perché i tuoi campi sono troppo piccoli.


4
I miei due centesimi, penso che introdurre il fallimento sia una buona cosa. Voglio sapere se i miei dati non corrispondono al formato / dimensione dei miei dati previsti. Cerco sempre di definire la mia tabella usando CREATE TABLEe poi INSERT INTOanche, è più facile testare la SELECTdichiarazione da sola, senza eseguire l'inserimento.
Doug Chamberlain,

1
@Doug - Sono d'accordo. Uso quasi esclusivamente SELECT INTOper creare una tabella temporanea o per eseguire un backup rapido di una tabella esistente con cui eseguirò il monkeying.
JNK,

1
@JNK - Da BOL, SELECT INTO crea una tabella con una struttura basata sui tipi di dati delle colonne nell'elenco di selezione. Quindi nel tuo esempio potresti correggere la situazione lanciando esplicitamente varchar in una dimensione che sarebbe sufficiente. Corretta?
jowenece,

2
@Jowenece - sì, mi aspetto così. Se sto andando a quel problema, andrò avanti e userò una CREATEdichiarazione però.
JNK,

24
  1. Quale affermazione è preferibile? Dipende da cosa stai facendo.

  2. Ci sono altre implicazioni sulle prestazioni? Se la tabella è una tabella permanente, è possibile creare indici al momento della creazione della tabella che ha implicazioni per le prestazioni sia negativamente che positivamente. Selezionare in non ricrea gli indici esistenti nelle tabelle correnti e pertanto l'utilizzo successivo della tabella potrebbe essere più lento di quanto non debba essere.

  3. Qual è un buon caso d'uso per SELECT ... INTO su INSERT INTO ...? Seleziona in viene utilizzato se potresti non conoscere in anticipo la struttura della tabella. È più veloce scrivere che creare una tabella e un'istruzione insert, quindi a volte viene utilizzato per accelerare lo sviluppo. Spesso è più veloce da utilizzare quando si crea una tabella temporanea rapida per testare le cose o una tabella di backup di una query specifica (forse i record che si intende eliminare). Dovrebbe essere raro vederlo usato nel codice di produzione che verrà eseguito più volte (ad eccezione delle tabelle temporanee) perché non funzionerà se la tabella era già esistente.

A volte viene utilizzato in modo inappropriato da persone che non sanno cosa stanno facendo. E di conseguenza possono causare il caos nel db. Sento fortemente inappropriato usare SELECT INTO per qualcosa di diverso da una tabella usa e getta (un backup temporaneo, una tabella temporanea che andrà via alla fine del processo memorizzato, ecc.). Le tabelle permanenti necessitano di una vera riflessione sul loro design e SELECT INTO semplifica l'evitamento di pensare a qualsiasi cosa anche di base come colonne e tipi di dati.

In generale, preferisco l'uso della tabella create e dell'istruzione insert: hai più controlli ed è meglio per i processi ripetibili. Inoltre, se la tabella è una tabella permanente, dovrebbe essere creata da uno script di creazione tabella separato (uno che si trova nel controllo del codice sorgente) poiché la creazione di oggetti permanenti non dovrebbe, in generale, nel codice essere inserimenti / eliminazioni / aggiornamenti o seleziona da un tavolo. Le modifiche agli oggetti devono essere gestite separatamente dalle modifiche ai dati poiché gli oggetti hanno implicazioni oltre le esigenze di un inserimento / aggiornamento / selezione / eliminazione specifici. È necessario considerare i migliori tipi di dati, pensare ai vincoli FK, PK e altri vincoli, considerare i requisiti di controllo, pensare all'indicizzazione, ecc.


5

La differenza principale è che SELECT INTO MyTable creerà una nuova tabella chiamata MyTable con i risultati, mentre INSERT INTO richiede che MyTable esista già.

Utilizzeresti SELECT INTO solo nel caso in cui la tabella non esistesse e volessi crearla in base ai risultati della tua query. In quanto tali, queste due affermazioni in realtà non sono comparabili. Fanno cose molto diverse.

In generale, SELECT INTO viene utilizzato più spesso per attività una tantum, mentre INSERT INTO viene utilizzato regolarmente per aggiungere righe alle tabelle.

EDIT:
Mentre puoi usare CREATE TABLE e INSERT INTO per realizzare ciò che SELECT INTO fa, con SELECT INTO non devi conoscere in anticipo la definizione della tabella. SELECT INTO è probabilmente incluso in SQL perché semplifica notevolmente attività come la creazione di report ad hoc o la copia di tabelle.


CREATE TABLE e SELECT INTO sono praticamente la stessa cosa (non è necessario INSERT INTO come aggiunta per realizzare ciò che SELECT INTO fa) e SELECT INTO non è raccomandato, credo. Vedi dba.stackexchange.com/questions/156105/… .
Rick,

4

Ogni istruzione ha un caso d'uso distinto. Non sono intercambiabili.

SELECT...INTO MyTable...crea un nuovo MyTabledove uno non esisteva prima.

INSERT INTO MyTable...SELECT...viene utilizzato quando MyTableesiste già.


4
Non hai risposto a nessuna delle mie domande e ho già dichiarato la tua risposta.
jowenece,

5
Le risposte alle tue domande sono implicite. Per renderlo più chiaro, non esiste un'istruzione "preferibile" poiché ognuna ha un caso d'uso distinto. Le dichiarazioni non sono intercambiabili. Utilizzare la prima versione quando si desidera creare una nuova tabella che non esiste. Utilizzare la seconda versione quando la tabella esiste già.
Joe Stefanelli,

2
Perché dovrei voler farlo vs creare una tabella temporanea e quindi inserirla in essa? C'è un vantaggio?
jowenece,

4

In realtà SELECT ... INTO non solo crea la tabella, ma fallirà se esiste già, quindi sostanzialmente l'unica volta che la useresti è quando la tabella che stai inserendo non esiste.

Per quanto riguarda il tuo EDIT:

Personalmente uso principalmente SELECT ... INTO quando creo una tabella temporanea. Questo per me è l'uso principale. Tuttavia lo uso anche quando creo nuove tabelle con molte colonne con strutture simili ad altre tabelle e poi le modifico per risparmiare tempo.


1
Vedo principalmente gli usi di SELECT..INTO anche per le tabelle temporanee, ma c'è un motivo per preferire questo rispetto alla creazione di una tabella temporanea con un'istruzione CREATE TABLE? Ad esempio: aumento delle prestazioni?
jowenece,

3
@jowenece Penso principalmente per semplicità ... Dì anche che hai una query dinamica. Se non conosci la struttura, non puoi creare prima la tabella, ed è molto più facile usare SELEZIONA ... INTO piuttosto che creare una tabella in modo dinamico.
AJC,

3

SELECT INTO viene generalmente utilizzato per generare tabelle temporanee o per copiare un'altra tabella (dati e / o struttura).

Nel codice quotidiano usi INSERT perché le tue tabelle dovrebbero già esistere per essere lette, UPDATEd, DELETEd, JOINed ecc. Nota: la parola chiave INTO è facoltativa con INSERT

Cioè, le applicazioni normalmente non creeranno e rilasceranno le tabelle come parte delle normali operazioni a meno che non sia una tabella temporanea per un uso limitato e specifico dell'ambito.

Una tabella creata da SELECT INTO non avrà chiavi o indici o vincoli a differenza di una tabella reale, persistente e già esistente

I 2 non sono direttamente comparabili perché non hanno quasi nessuna sovrapposizione nell'uso


2

Voglio solo coprire il secondo punto della domanda relativa alle prestazioni, perché nessun altro ha affrontato questo problema. Selezionare Into è molto più veloce di inserire in, quando si tratta di tabelle con set di dati di grandi dimensioni. Preferisco selezionare in quando devo leggere una tabella molto grande. inserire in per una tabella con 10 milioni di righe può richiedere ore mentre la selezione in lo farà in pochi minuti e per quanto riguarda la perdita di indici sulla nuova tabella, è possibile ricreare gli indici per query e risparmiare ancora molto più tempo rispetto a inserire.


È vero, ma principalmente perché SQL Server sa che non esiste contesa per la tabella di destinazione. La performance insert into #temp with(tablock) select * from ..è più o meno la stessa diselect * into #temp from ...
Brian

1

Selezionare in crea una nuova tabella per te in quel momento e quindi inserire i record nella tabella di origine. La tabella appena creata ha la stessa struttura della tabella di origine. Se si tenta di utilizzare select in per una tabella esistente, verrà generato un errore, poiché tenterà di creare una nuova tabella con lo stesso nome. Inserisci in richiede che la tabella sia presente nel database prima di inserire le righe al suo interno.


1

La semplice differenza tra selezionare Into e Inserisci in è: -> Seleziona In non è necessaria la tabella esistente. Se si desidera copiare i dati della tabella A, è sufficiente digitare Select * INTO [tablename] da A. Qui, tablename può essere una tabella esistente o verrà creata una nuova tabella con la stessa struttura della tabella A.

-> Inserisci in per aver bisogno della tabella esistente. INSERISCI IN [tablename] SELEZIONA * DA A ;. Qui tablename è una tabella esistente.

Selezionare In è di solito più popolare per copiare i dati, in particolare i dati di backup.

Puoi usare secondo le tue esigenze, è una scelta totalmente da sviluppatore che dovrebbe essere usata nel suo scenario.

Per quanto riguarda le prestazioni, Insert INTO è veloce.

Riferimenti :

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


-2

Selezionare in per insiemi di dati di grandi dimensioni può essere utile solo per un singolo utente che utilizza una singola connessione al database che esegue un'attività in blocco. Non consiglio di usare

SELECT * INTO table

poiché ciò crea una grande transazione e crea il blocco dello schema per creare l'oggetto, impedendo ad altri utenti di creare oggetti o accedere agli oggetti di sistema fino al SELECT INTOcompletamento dell'operazione.

Come prova del concetto aprire 2 sessioni, nella prima sessione provare a utilizzare

select into temp table from a huge table 

e nella seconda sezione prova a

create a temp table 

e controlla i blocchi, i blocchi e la durata della seconda sessione per creare un oggetto tabella temporanea. La mia raccomandazione è sempre una buona pratica per creare e inserire istruzioni e, se necessario, per la registrazione minima utilizzare il flag di traccia 610.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.