INSERT INTO vs SELECT INTO

127

Jaka jest różnica między using

SELECT ... INTO MyTable FROM...

i

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

?

Z BOL [ INSERT , SELECT ... INTO ] wiem, że użycie polecenia SELECT ... INTO utworzy tabelę wstawiania w domyślnej grupie plików, jeśli jeszcze nie istnieje, i że rejestrowanie tej instrukcji zależy od odzyskiwania model bazy danych.

  1. Które stwierdzenie jest lepsze?
  2. Czy są inne konsekwencje dla wydajności?
  3. Jaki jest dobry przypadek użycia SELECT ... INTO zamiast INSERT INTO ...?

Edycja: Powiedziałem już, że wiem, że SELECT INTO ... tworzy tabelę tam, gdzie jej nie ma. Chcę wiedzieć, że SQL zawiera tę instrukcję z jakiegoś powodu, co to jest? Czy robi coś innego za kulisami w celu wstawiania wierszy, czy jest to po prostu cukier syntaktyczny na wierzchu CREATE TABLEi INSERT INTO.

jowenece
źródło
Jeden mały czynnik: INSERT INTOma dwa słowa kluczowe (wybierz i do) na samym początku, które informują świat, że nie jest to zwykła instrukcja SQL, a SELECT ... INTOzaczyna przynajmniej wyglądać jak zwykła instrukcja SQL. Mały powód, by faworyzować to pierwsze.
Martin F

Odpowiedzi:

122
  1. Robią różne rzeczy. Użyj, INSERTgdy istnieje tabela. Użyj, SELECT INTOgdy tak się nie dzieje.

  2. Tak. INSERTbez podpowiedzi do tabeli jest zwykle rejestrowana. SELECT INTOjest minimalnie rejestrowany przy założeniu, że ustawione są odpowiednie flagi śledzenia.

  3. Z mojego doświadczenia SELECT INTOwynika, że ​​jest najczęściej używany z pośrednimi zestawami danych, takimi jak #temptabele, lub do kopiowania całej tabeli, jak w przypadku kopii zapasowej. INSERT INTOjest używany podczas wstawiania do istniejącej tabeli o znanej strukturze.

EDYTOWAĆ

Aby zająć się Twoją zmianą, robią różne rzeczy. Jeśli tworzysz tabelę i chcesz zdefiniować strukturę, użyj CREATE TABLEi INSERT. Przykład problemu, który można utworzyć: Masz małą tabelkę z polem varchar. Największy ciąg w twojej tabeli ma teraz 12 bajtów. Twój prawdziwy zestaw danych będzie potrzebował do 200 bajtów. Jeśli zrobisz SELECT INTOz małej tabeli nową tabelę, późniejsza INSERTzakończy się błędem obcinania, ponieważ pola są za małe.

JNK
źródło
4
Moje dwa centy, myślę, że wprowadzenie porażki to dobra rzecz. Chcę wiedzieć, czy moje dane nie odpowiadają oczekiwanemu formatowi / rozmiarowi danych. Zawsze staram się zdefiniować moją tabelę za pomocą, CREATE TABLEa następnie INSERT INTOłatwiej jest przetestować SELECTinstrukcję samodzielnie, bez wykonywania wstawiania.
Doug Chamberlain
1
@Doug - zgadzam się. Używam prawie wyłącznie SELECT INTOdo tworzenia tabeli tymczasowej lub do szybkiego tworzenia kopii zapasowej istniejącej tabeli, z którą będę małpować.
JNK
1
@JNK - Z BOL, SELECT INTO tworzy tabelę ze strukturą opartą na typach danych kolumn na liście wyboru. Więc w swoim przykładzie możesz naprawić sytuację, jawnie rzutując varchar na wystarczający rozmiar. Poprawny?
jowenece
2
@Jowenece - tak, spodziewam się. Jeśli będę miał kłopoty, to jednak posłużę się CREATEoświadczeniem.
JNK
24
  1. Które stwierdzenie jest lepsze? Zależy od tego, co robisz.

  2. Czy są inne konsekwencje dla wydajności? Jeśli tabela jest tabelą trwałą, możesz utworzyć indeksy w czasie tworzenia tabeli, co ma wpływ na wydajność zarówno negatywnie, jak i pozytywnie. Opcja Select into nie tworzy ponownie indeksów, które istnieją w bieżących tabelach, dlatego późniejsze użycie tabeli może być wolniejsze niż powinno.

  3. Jaki jest dobry przypadek użycia SELECT ... INTO zamiast INSERT INTO ...? Wybierz opcję into, jeśli nie znasz wcześniej struktury tabeli. Zapisywanie jest szybsze niż tworzenie tabeli i instrukcji wstawiania, więc czasami służy do przyspieszenia rozwoju. Często jest szybszy w użyciu, gdy tworzysz tabelę tymczasową do testowania lub kopię zapasową tabeli określonego zapytania (może to być rekordy, które zamierzasz usunąć). Powinno być rzadkie, aby był używany w kodzie produkcyjnym, który będzie uruchamiany wiele razy (z wyjątkiem tabel tymczasowych), ponieważ zakończy się niepowodzeniem, jeśli tabela już istniała.

Czasami jest niewłaściwie używany przez ludzi, którzy nie wiedzą, co robią. W rezultacie mogą spowodować spustoszenie w bazie danych. Zdecydowanie uważam, że używanie polecenia SELECT INTO do czegoś innego niż jednorazowa tabela (tymczasowa kopia zapasowa, tabela tymczasowa, która zniknie po zakończeniu przechowywanego procesu itp.) Jest niewłaściwe. Stałe tabele wymagają prawdziwego przemyślenia co do ich projektu, a funkcja SELECT INTO ułatwia uniknięcie myślenia o czymkolwiek, nawet tak podstawowym, jak kolumny i typy danych.

Generalnie wolę używać instrukcji create table i insert - masz więcej kontrolek i jest to lepsze dla powtarzalnych procesów. Ponadto, jeśli tabela jest tabelą trwałą, powinna zostać utworzona z oddzielnego skryptu tworzenia tabeli (takiego, który jest w kontroli źródła), ponieważ tworzenie trwałych obiektów nie powinno, ogólnie rzecz biorąc, w kodzie wstawiać / usuwać / aktualizować lub wybierać z stół. Zmiany obiektów powinny być obsługiwane oddzielnie od zmian danych, ponieważ obiekty mają konsekwencje wykraczające poza potrzeby konkretnego wstawiania / aktualizowania / wybierania / usuwania. Musisz wziąć pod uwagę najlepsze typy danych, pomyśleć o ograniczeniach FK, PK i innych ograniczeniach, rozważyć wymagania audytowe, pomyśleć o indeksowaniu itp.

HLGEM
źródło
5

Podstawowa różnica polega na tym, że SELECT INTO MyTable utworzy nową tabelę o nazwie MyTable z wynikami, podczas gdy INSERT INTO wymaga, aby MyTable już istniał.

Użyj polecenia SELECT INTO tylko w przypadku, gdy tabela nie istnieje, a chcesz ją utworzyć na podstawie wyników zapytania. Jako takie, te dwa stwierdzenia naprawdę nie są porównywalne. Robią bardzo różne rzeczy.

Ogólnie rzecz biorąc, SELECT INTO jest używane częściej w przypadku jednorazowych zadań, podczas gdy INSERT INTO jest używane regularnie do dodawania wierszy do tabel.

EDIT:
Chociaż możesz użyć CREATE TABLE i INSERT INTO, aby wykonać to, co robi SELECT INTO, z SELECT INTO nie musisz wcześniej znać definicji tabeli. SELECT INTO jest prawdopodobnie zawarte w SQL, ponieważ znacznie ułatwia zadania takie jak raportowanie ad hoc lub kopiowanie tabel.

rsbarro
źródło
CREATE TABLE i SELECT INTO to prawie to samo (nie potrzeba INSERT INTO jako dodatku do osiągnięcia tego, co robi SELECT INTO), a SELECT INTO nie jest zalecane. Zobacz dba.stackexchange.com/questions/156105/… .
Rick
4

Każda instrukcja ma inny przypadek użycia. Nie są wymienne.

SELECT...INTO MyTable...tworzy nowy MyTabletam, gdzie wcześniej go nie było.

INSERT INTO MyTable...SELECT...jest używany, gdy MyTablejuż istnieje.

Joe Stefanelli
źródło
4
Nie odpowiedziałeś na żadne z moich pytań, a ja już odpowiedziałem.
jowenece
5
Odpowiedzi na twoje pytania są implikowane. Aby było jaśniej, nie ma „preferowanego” stwierdzenia, ponieważ każde z nich ma odrębny przypadek użycia. Oświadczenia nie są zamienne. Użyj pierwszej wersji, jeśli chcesz utworzyć nową tabelę, która nie istnieje. Użyj drugiej wersji, gdy tabela już istnieje.
Joe Stefanelli
2
Dlaczego miałbym to robić, a nie tworzyć tabeli tymczasowej, a następnie wstawiać do niej? Czy jest jakaś korzyść?
jowenece
4

Właściwie SELECT ... INTO nie tylko tworzy tabelę, ale zakończy się niepowodzeniem, jeśli już istnieje, więc w zasadzie jedyny raz, kiedy możesz jej użyć, to wtedy, gdy tabela, do której wstawiasz, nie istnieje.

W odniesieniu do Twojej EDYCJI:

Osobiście używam głównie SELECT ... INTO podczas tworzenia tabeli tymczasowej. To jest dla mnie główne zastosowanie. Jednak używam go również podczas tworzenia nowych tabel z wieloma kolumnami o podobnej strukturze do innych tabel, a następnie edytuję go, aby zaoszczędzić czas.

AJC
źródło
1
Widzę głównie zastosowania SELECT..INTO również dla tabel tymczasowych, ale czy istnieje powód, aby preferować, że zamiast tworzenia tabeli tymczasowej z instrukcją CREATE TABLE? Np. - wzrost wydajności?
jowenece
3
@jowenece Myślę, że głównie dla prostoty ... Powiedz też, że masz dynamiczne zapytanie. Jeśli nie znasz struktury, nie możesz utworzyć tabeli wcześniej, a użycie polecenia SELECT ... INTO jest o wiele łatwiejsze niż tworzenie tabeli w sposób dynamiczny.
AJC
3

Funkcja SELECT INTO jest zwykle używana do generowania tabel tymczasowych lub do kopiowania innej tabeli (danych i / lub struktury).

W codziennym kodzie używasz INSERT, ponieważ twoje tabele powinny już istnieć, aby je odczytać, UPDATEd, DELETEd, JOINed itp. Uwaga: słowo kluczowe INTO jest opcjonalne w przypadku INSERT

Oznacza to, że aplikacje normalnie nie tworzą i nie usuwają tabel w ramach normalnych operacji, chyba że jest to tabela tymczasowa dla pewnego zakresu ograniczonego i określonego zastosowania.

Tabela utworzona przez SELECT INTO nie będzie miała kluczy, indeksów ani ograniczeń w przeciwieństwie do rzeczywistej, utrwalonej, już istniejącej tabeli

Te 2 nie są bezpośrednio porównywalne, ponieważ w użyciu prawie nie pokrywają się

gbn
źródło
2

Chcę tylko omówić drugi punkt pytania, który jest związany z wydajnością, ponieważ żaden inny organ nie omówił tego. Opcja Select Into jest znacznie szybsza niż wstawianie do, jeśli chodzi o tabele z dużymi zbiorami danych. Wolę wybierać, gdy muszę czytać z bardzo dużej tabeli. wstawianie do dla tabeli z 10 milionami wierszy może zająć godziny, podczas gdy wybór w zrobi to w ciągu kilku minut, a jeśli chodzi o utratę indeksów w nowej tabeli, możesz ponownie utworzyć indeksy za pomocą zapytania i nadal możesz zaoszczędzić znacznie więcej czasu w porównaniu z włóż w.

Niraj
źródło
To prawda, ale dzieje się tak głównie dlatego, że SQL Server wie, że nie ma rywalizacji o tabelę docelową. Wykonanie dla insert into #temp with(tablock) select * from ..jest mniej więcej takie samo, jak dlaselect * into #temp from ...
Briana
1

Wybierz w tworzy nową tabelę dla Ciebie w tym czasie, a następnie wstaw do niej rekordy z tabeli źródłowej. Nowo utworzona tabela ma taką samą strukturę jak tabela źródłowa. Jeśli spróbujesz użyć funkcji select into dla istniejącej tabeli, spowoduje to błąd, ponieważ spróbuje utworzyć nową tabelę o tej samej nazwie. Opcja Wstaw do wymaga, aby tabela istniała w bazie danych przed wstawieniem do niej wierszy.

Satish Vishwakarma
źródło
1

Prosta różnica między opcjami Select Into i Insert Into jest następująca: -> Wybierz do nie wymaga istniejącej tabeli. Jeśli chcesz skopiować dane tabeli A, po prostu wpisz Select * INTO [nazwa tabeli] z A. Tutaj nazwa tabeli może być istniejącą tabelą lub zostanie utworzona nowa tabela, która ma taką samą strukturę jak tabela A.

-> Wstaw do, aby potrzebować istniejącej tabeli. INSERT INTO [nazwa tabeli] SELECT * FROM A ;. Tutaj nazwa tabeli to istniejąca tabela.

Opcja Select Into jest zwykle bardziej popularna w przypadku kopiowania danych, zwłaszcza kopii zapasowych.

Możesz używać zgodnie ze swoimi wymaganiami, jest to całkowicie wybór programisty, który powinien być użyty w jego scenariuszu.

Pod względem wydajności Insert INTO jest szybki.

Bibliografia :

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

Aditya Parmar
źródło
-2

Wybierz opcję w przypadku dużych zestawów danych, która może być dobra tylko dla jednego użytkownika korzystającego z jednego połączenia z bazą danych wykonującego zadanie operacji zbiorczej. Nie polecam używać

SELECT * INTO table

ponieważ tworzy to jedną dużą transakcję i tworzy blokadę schematu w celu utworzenia obiektu, uniemożliwiając innym użytkownikom tworzenie obiektu lub dostęp do obiektów systemowych do czasu zakończenia SELECT INTOoperacji.

Jako dowód koncepcji otwórz 2 sesje, w pierwszej sesji spróbuj użyć

select into temp table from a huge table 

aw drugiej sekcji spróbuj

create a temp table 

i sprawdź blokady, blokady i czas trwania drugiej sesji, aby utworzyć obiekt tabeli tymczasowej. Moim zaleceniem jest zawsze tworzenie i wstawianie instrukcji, a jeśli jest to konieczne do minimalnego rejestrowania, użyj flagi śledzenia 610.

user6802184
źródło