INSERT INTO vs SELECT INTO

127

Qual é a diferença entre usar

SELECT ... INTO MyTable FROM...

e

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

?

No BOL [ INSERT , SELECT ... INTO ], eu sei que o uso de SELECT ... INTO criará a tabela de inserção no grupo de arquivos padrão, se ele ainda não existir, e que o log desta declaração depende da recuperação modelo do banco de dados.

  1. Qual afirmação é preferível?
  2. Existem outras implicações de desempenho?
  3. Qual é um bom caso de uso para SELECT ... INTO sobre INSERT INTO ...?

Edit: Eu já afirmei que sei que SELECT INTO ... cria uma tabela onde ela não existe. O que eu quero saber é que o SQL inclui esta declaração por um motivo, o que é? Está fazendo algo diferente nos bastidores para inserir linhas, ou é apenas açúcar sintático em cima de um CREATE TABLEe INSERT INTO.

jowenece
fonte
Um pequeno fator: INSERT INTOpossui duas palavras-chave (selecione e insira) logo no início, que avisam ao mundo que essa não é uma instrução SQL comum, enquanto SELECT ... INTOcomeçam, pelo menos, a parecer uma instrução SQL comum. Um pequeno motivo para favorecer o primeiro.
Martin F

Respostas:

122
  1. Eles fazem coisas diferentes. Use INSERTquando a tabela existir. Use SELECT INTOquando não estiver.

  2. Sim. INSERTsem dicas de tabela é normalmente registrado. SELECT INTOé minimamente registrado, assumindo que os sinalizadores de rastreio adequados estão definidos.

  3. Na minha experiência, SELECT INTOé mais comumente usado com conjuntos de dados intermediários, como #temptabelas, ou para copiar uma tabela inteira como para um backup. INSERT INTOé usado quando você insere em uma tabela existente com uma estrutura conhecida.

EDITAR

Para resolver sua edição, eles fazem coisas diferentes. Se você está criando uma tabela e deseja definir a estrutura, use CREATE TABLEe INSERT. Exemplo de um problema que pode ser criado: Você possui uma pequena tabela com um campo varchar. A maior string da sua tabela agora é de 12 bytes. Seu conjunto de dados reais precisará de até 200 bytes. Se você fizer SELECT INTOda sua pequena tabela uma nova, a última INSERTfalhará com um erro de truncamento porque seus campos são muito pequenos.

JNK
fonte
4
Meus dois centavos, acho que a introdução do fracasso é uma coisa boa. Quero saber se meus dados não correspondem ao formato / tamanho esperado. Eu sempre tento definir minha tabela usando CREATE TABLEe, em seguida INSERT INTO, Além disso, é mais fácil testar a SELECTinstrução sozinha, sem executar a inserção.
Doug Chamberlain
1
@ Doug - eu concordo. Eu quase exclusivamente uso SELECT INTOpara fazer uma tabela temporária ou fazer um backup rápido de uma tabela existente com a qual eu vou trabalhar.
JNK
1
@JNK - No BOL, SELECT INTO cria uma tabela com uma estrutura baseada nos tipos de dados das colunas na lista de seleção. Portanto, em seu exemplo, você pode corrigir a situação lançando explicitamente o varchar para um tamanho que seria suficiente. Corrigir?
precisa saber é o seguinte
2
@ Jowenece - sim, eu espero que sim. Se eu estiver enfrentando esse problema, vou seguir em frente e usar uma CREATEdeclaração.
JNK
24
  1. Qual afirmação é preferível? Depende do que você está fazendo.

  2. Existem outras implicações de desempenho? Se a tabela for uma tabela permanente, você poderá criar índices no momento da criação da tabela, o que tem implicações para o desempenho, tanto negativa quanto positivamente. Selecionar em não recriar índices existentes nas tabelas atuais e, portanto, o uso subsequente da tabela pode ser mais lento do que o necessário.

  3. Qual é um bom caso de uso para SELECT ... INTO sobre INSERT INTO ...? Selecionar em é usado se você não conhece a estrutura da tabela com antecedência. É mais rápido escrever do que criar tabela e uma instrução insert, por isso é usado para acelerar o desenvolvimento às vezes. Geralmente, é mais rápido usar quando você está criando uma tabela temporária rápida para testar coisas ou uma tabela de backup de uma consulta específica (talvez os registros que você deseja excluir). Deve ser raro vê-lo usado no código de produção que será executado várias vezes (exceto nas tabelas temporárias) porque ocorrerá falha se a tabela já existir.

Às vezes, é usado de forma inadequada por pessoas que não sabem o que estão fazendo. E eles podem causar estragos no banco de dados como resultado. Eu sinto fortemente que é inapropriado usar SELECT INTO para algo que não seja uma tabela descartável (um backup temporário, uma tabela temporária que desaparecerá no final do processo armazenado, etc.). As tabelas permanentes precisam de uma reflexão real sobre seu design, e SELECT INTO facilita evitar pensar em algo tão básico quanto quais colunas e quais tipos de dados.

Em geral, prefiro o uso da tabela create e da instrução insert - você tem mais controles e é melhor para processos repetíveis. Além disso, se a tabela for uma tabela permanente, ela deverá ser criada a partir de um script de tabela de criação separado (um que esteja no controle de origem), pois a criação de objetos permanentes não deve, em geral, no código serem inserções / exclusões / atualizações ou seleções de um tabela. As alterações de objetos devem ser tratadas separadamente das alterações de dados, pois os objetos têm implicações além das necessidades de uma inserção / atualização / seleção / exclusão específica. Você precisa considerar os melhores tipos de dados, pensar em restrições de FK, PKs e outras restrições, considerar requisitos de auditoria, pensar em indexação etc.

HLGEM
fonte
5

A principal diferença é que SELECT INTO MyTable criará uma nova tabela chamada MyTable com os resultados, enquanto INSERT INTO exige que MyTable já exista.

Você usaria SELECT INTO apenas no caso em que a tabela não existisse e desejasse criá-la com base nos resultados da sua consulta. Como tal, essas duas declarações realmente não são comparáveis. Eles fazem coisas muito diferentes.

Em geral, SELECT INTO é usado com mais frequência para tarefas pontuais, enquanto INSERT INTO é usado regularmente para adicionar linhas às tabelas.

EDIT:
Embora você possa usar CREATE TABLE e INSERT INTO para realizar o que SELECT INTO faz, com SELECT INTO você não precisa conhecer a definição da tabela antes. O SELECT INTO provavelmente está incluído no SQL porque facilita tarefas como relatórios ad hoc ou copiar tabelas.

rsbarro
fonte
CREATE TABLE e SELECT INTO são praticamente a mesma coisa (não é necessário INSERT INTO como complemento para realizar o que SELECT INTO faz) e SELECT INTO não é recomendado, eu acho. Consulte dba.stackexchange.com/questions/156105/… .
21418 Rick
4

Cada instrução possui um caso de uso distinto. Eles não são intercambiáveis.

SELECT...INTO MyTable...cria um novo MyTableonde um não existia antes.

INSERT INTO MyTable...SELECT...é usado quando MyTablejá existe.

Joe Stefanelli
fonte
4
Você não respondeu nenhuma das minhas perguntas e eu já afirmei sua resposta.
precisa saber é o seguinte
5
As respostas para suas perguntas estão implícitas. Para tornar mais claro, não há nenhuma instrução "preferível", pois cada uma possui um caso de uso distinto. As declarações não são intercambiáveis. Use a primeira versão quando desejar criar uma nova tabela que não existe. Use a segunda versão quando a tabela já existir.
Joe Stefanelli
2
Por que eu faria isso vs criar uma tabela temporária e depois inseri-la? Existe uma vantagem?
precisa saber é o seguinte
4

Na verdade, SELECT ... INTO não apenas cria a tabela, mas também falhará se ela já existir. Portanto, basicamente, o único momento em que você a utilizaria é quando a tabela na qual você está inserindo não existir.

Em relação ao seu EDIT:

Pessoalmente, uso principalmente SELECT ... INTO quando estou criando uma tabela temporária. Isso para mim é o principal uso. No entanto, eu também o uso ao criar novas tabelas com muitas colunas com estruturas semelhantes a outras tabelas e depois editá-las para economizar tempo.

AJC
fonte
1
Eu vejo principalmente usos de SELECT..INTO para tabelas temporárias também, mas existe um motivo para preferir isso ao criar uma tabela temporária com uma instrução CREATE TABLE? Por exemplo - ganho de desempenho?
precisa saber é o seguinte
3
@ jowenece Penso principalmente por simplicidade ... Diga também que você tem uma consulta dinâmica. Você não conhece a estrutura, não pode criar a tabela antes e é muito mais fácil usar SELECT ... INTO do que criar uma tabela dinamicamente.
AJC
3

SELECT INTO normalmente é usado para gerar tabelas temporárias ou copiar outra tabela (dados e / ou estrutura).

No código do dia a dia, você usa INSERT porque suas tabelas já devem existir para serem lidas, UPDATEd, DELETEd, JOINed etc. Nota: a palavra-chave INTO é opcional com INSERT

Ou seja, os aplicativos normalmente não criam e descartam tabelas como parte das operações normais, a menos que seja uma tabela temporária para algum uso limitado e específico do escopo.

Uma tabela criada por SELECT INTO não terá chaves, índices ou restrições, ao contrário de uma tabela real, persistente e já existente

Os 2 não são diretamente comparáveis ​​porque quase não têm sobreposição no uso

gbn
fonte
2

Eu só quero cobrir o segundo ponto da questão que está relacionada ao desempenho, porque nenhum outro órgão cobriu isso. Selecionar em é muito mais rápido do que inserir, quando se trata de tabelas com grandes conjuntos de dados. Prefiro selecionar quando preciso ler uma tabela muito grande. inserir em uma tabela com 10 milhões de linhas pode levar horas, enquanto a opção selecionar fará isso em minutos. Quanto à perda de índices em uma nova tabela, você pode recriar os índices por consulta e ainda economizar muito mais tempo em comparação com insira dentro de.

Niraj
fonte
Isso é verdade, mas principalmente porque o SQL Server sabe que não há contenção para a tabela de destino. O desempenho de insert into #temp with(tablock) select * from ..é aproximadamente o mesmo que o desempenho paraselect * into #temp from ...
Brian
1

Selecione para criar uma nova tabela para você no momento e insira registros nela na tabela de origem. A tabela recém-criada tem a mesma estrutura que a tabela de origem. Se você tentar usar select em uma tabela existente, ela produzirá um erro, porque tentará criar uma nova tabela com o mesmo nome. Inserir requer que a tabela exista no seu banco de dados antes de inserir linhas nele.

Satish Vishwakarma
fonte
1

A diferença simples entre selecionar Em e Inserir em é: -> Selecionar em não precisa da tabela existente. Se você deseja copiar os dados da tabela A, basta digitar Select * INTO [nome da tabela] em A. Aqui, o nome da tabela pode ser uma tabela existente ou uma nova tabela será criada com a mesma estrutura da tabela A.

-> Inserir em precisa da tabela existente.INSERT INTO [nome da tabela] SELECT * FROM A ;. Aqui tablename é uma tabela existente.

Selecionar em geralmente é mais popular para copiar dados, especialmente dados de backup.

Você pode usar conforme sua necessidade, é totalmente a escolha do desenvolvedor que deve ser usada em seu cenário.

Em termos de desempenho, o Insert INTO é rápido.

Referências :

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

Aditya Parmar
fonte
-2

Selecionar para conjuntos de dados grandes pode ser bom apenas para um único usuário usando uma única conexão com o banco de dados executando uma tarefa de operação em massa. Eu não recomendo usar

SELECT * INTO table

pois isso cria uma grande transação e cria um bloqueio de esquema para criar o objeto, impedindo que outros usuários criem objetos ou acessem objetos do sistema até que a SELECT INTOoperação seja concluída.

Como prova de conceito, abra 2 sessões, na primeira sessão tente usar

select into temp table from a huge table 

e na segunda seção tente

create a temp table 

e verifique os bloqueios, o bloqueio e a duração da segunda sessão para criar um objeto de tabela temporária. Minha recomendação é sempre uma boa prática para criar e inserir instruções e, se necessário para o mínimo de log, use o sinalizador de rastreamento 610.

user6802184
fonte