Creative Saplings

Quando usar a instrução SELECT… INTO (PE003)

Outubro 13, 2020
No Comments

Podemos usar SELECT…INTO no SQL Server para criar uma nova tabela a partir de uma fonte de tabela. O SQL Server usa os atributos das expressões na lista SELECT para definir a estrutura da nova tabela.

Antes do SQL Server 2005, o uso de SELECT…INTO no código de produção era um ‘cheiro de código’ de desempenho porque adquiria bloqueios de esquema nas tabelas do sistema do banco de dados, fazendo com que o SQL Server parecesse sem resposta enquanto a consulta estava sendo executada. Isso ocorre porque é uma instrução DDL em uma transação implícita, que é inevitavelmente longa, pois os dados são inseridos na mesma instrução SQL. No entanto, esse comportamento foi corrigido no SQL Server 2005, quando o modelo de bloqueio mudou.

SELECT…INTO tornou-se popular porque era uma maneira mais rápida de inserir dados do que usar INSERT INTO…SELECT…. Isso se deveu principalmente ao fato de a operação SELECT…INTO ser, onde possível, registrada em massa. Embora INSERT INTO agora possa ser registrado em massa, você ainda pode ver essa vantagem de desempenho no SQL Server 2012 e 2014, porque SELECT…INTO pode ser paralelizado nessas versões, enquanto o suporte para paralelização de INSERT INTO surgiu apenas no SQL Server 2016. No entanto, com SELECT…INTO, você ainda tem a tarefa de definir todos os índices e restrições necessários, e assim por diante, na nova tabela.

Uma recomendação para evite o uso de SELECT…INTO, para código de produção, está incluído como uma regra de análise de código no prompt SQL (PE003).

Criação de tabelas usando a instrução SELECT INTO

O recurso SELECT…INTO no SQL Server foi projetado para armazenar ou ‘persistir’ uma fonte de tabela como parte de um processo. Aqui está um exemplo simples:

No entanto, uma fonte de tabela pode ser muito diferente de uma tabela convencional, como uma função definida pelo usuário, um OpenQuery, uma OpenDataSource, uma OPENXML cláusula, uma tabela derivada, uma tabela combinada, uma tabela dinâmica, uma fonte de dados remota, uma variável de tabela ou uma função variável. É com essas fontes de tabela mais exóticas que a sintaxe SELECT…INTO se torna mais útil.

É SELECT INTO parte do ANSI padrão?

Os padrões ANSI suportam uma construção SELECT…INTO; é chamado de seleção de singleton e carrega uma única linha com valores, mas é muito raramente usado (graças a Joe Celko por apontar isso).

As pessoas costumam usar SELECT…INTO com o mal-entendido de que é uma maneira rápida de copiar tabelas e, portanto, é uma surpresa que nenhum dos índices, restrições, colunas calculadas ou acionadores definidos em a tabela de origem é transferida para a nova tabela. Eles também não podem ser especificados na instrução SELECT…INTO. Ele também não faz nada sobre a nulidade ou preservação de colunas computadas. Todas essas tarefas devem ser feitas retrospectivamente com os dados no lugar, o que inevitavelmente leva tempo.

Você pode, no entanto, usar a função IDENTITY (tipo de dados, semente, incremento) para configurar um campo de identidade, e é possível, quando a origem for uma única tabela, transformar uma coluna da tabela de destino em uma coluna de identidade. É esse fato que provavelmente leva os desenvolvedores a presumir que ele irá transferir outros atributos de coluna.

Além disso, ele também não pode criar tabelas particionadas, colunas esparsas ou qualquer outro atributo herdado de uma tabela de origem. Como poderia, quando os dados podem vir de uma consulta envolvendo muitas junções ou de alguma fonte de dados externa exótica?

Desde o SQL 2012 SP1 CU10, SELECT…INTO pode ser executado em paralelo, no entanto, desde o SQL Server 2016, a inserção paralela foi permitida na instrução INSERT INTO…SELECT convencional, com certas restrições, portanto, qualquer vantagem de desempenho de usar SELECT… INTO agora está bastante reduzido. O INSERT INTO processo também pode ser acelerado se puder ser registrado em massa, em vez de totalmente recuperado, definindo o modelo de recuperação para registro simples ou em massa, inserindo em uma tabela vazia ou heap e definindo a TABLOCK dica para a tabela.

O seguinte resume algumas das restrições e limitações ao usar SELECT…INTO.

  • A propriedade IDENTITY de uma coluna é transferida, mas não se:
    • A instrução SELECT contém tabelas unidas (usando JOIN ou UNION), GROUP BY cláusula ou função agregada.Se você precisa evitar que uma propriedade IDENTITY seja transportada para a nova tabela, mas precisa dos valores da coluna, vale a pena adicionar um JOIN para sua tabela de origem em uma condição que nunca é verdadeira ou um UNION que não fornece linhas.
    • O IDENTITY a coluna é listada mais de uma vez na SELECT lista
    • A coluna IDENTITY faz parte de uma expressão
    • A coluna IDENTITY é de uma fonte de dados remota
  • Você não pode SELECT…INTO um parâmetro com valor de tabela ou uma variável de tabela como destino, embora você possa selecioná-los FROM.
  • Mesmo que sua origem é uma tabela particionada, a nova tabela é criada no grupo de arquivos padrão. No entanto, no SQL Server 2017, é possível especificar o grupo de arquivos no qual a tabela de destino é criada, por meio da cláusula ON.
  • Você pode especificar um ORDER BY cláusula, mas geralmente é ignorada. Por causa disso, a ordem de IDENTITY_INSERT não é garantida.
  • Quando uma coluna computada é incluída em SELECT lista, a coluna correspondente na nova tabela não é uma coluna computada. Os valores na nova coluna são os valores que foram calculados no momento em que SELECT…INTO foi executado.
  • Como com um CREATE TABLE declaração, se uma SELECT…INTO declaração estiver contida em uma transação explícita, as linhas subjacentes nas tabelas de sistema afetadas são bloqueado exclusivamente até que a transação seja explicitamente confirmada. Enquanto isso, isso resultará em bloqueios em outros processos que usam essas tabelas do sistema.

Há alguma confusão sobre os problemas que podem acontecer com o uso de SELECT…INTO usando tabelas temporárias. SELECT…INTO ganhou uma reputação um tanto injusta por isso, mas era parte de um problema mais geral envolvendo contenção de trava em tempdb sob uma carga pesada de criação e exclusão de pequenas tabelas temporárias. Quando SELECT…INTO foi adotado com entusiasmo, pode aumentar muito este tipo de atividade. O problema pode ser facilmente corrigido no SQL Server 2000 em diante com a introdução do uso do sinalizador de rastreamento TF1118, que não é mais necessário do SQL Server 2016 em diante. Para uma explicação completa, veja Equívocos em torno do TF 1118.

Resumo

Em resumo, SELECT…INTO é uma boa maneira de fazer uma tabela- fonte temporariamente persistente como parte de um processo, se você não se preocupa com restrições, índices ou colunas especiais. Não é uma boa maneira de copiar uma tabela porque apenas os fundamentos básicos do esquema da tabela podem ser copiados. Ao longo dos anos, houve fatores que aumentaram ou diminuíram a atração de SELECT…INTO, mas no geral é uma boa ideia evitar usá-lo sempre que possível. Em vez disso, crie uma tabela explicitamente, com toda a gama de recursos que a tabela possui, projetados para garantir que os dados sejam consistentes.

Articles
Previous Post

Células caliciformes: definição, funções, secreção de muco e doenças associadas

Next Post

Mistura de massa de pizza com farinha de amêndoa saudável e receita de massa (Paleo, sem glúten)

Deixe uma resposta Cancelar resposta

Artigos recentes

  • As melhores escolas de fotografia do mundo, 2020
  • Cidadãos soberanos levam sua filosofia antigovernamental para as estradas
  • Guia de custos de reparo de estuque
  • Muckrakers (Português)
  • Oncologia de precisão

Arquivo

  • Fevereiro 2021
  • Janeiro 2021
  • Dezembro 2020
  • Novembro 2020
  • Outubro 2020
  • Setembro 2020
  • Deutsch
  • Nederlands
  • Svenska
  • Norsk
  • Dansk
  • Español
  • Français
  • Português
  • Italiano
  • Română
  • Polski
  • Čeština
  • Magyar
  • Suomi
  • 日本語
  • 한국어
Proudly powered by WordPress | Theme: Fmi by Forrss.