Por que "Selecionar * no targettable do sourcetable" é mais rápido que "inserir no targettable select * do sourcetable

9

Este título é a pergunta. Estou curioso para saber a resposta. Alguém disse

select into está minimamente logado Banco de dados de modelo de recuperação simples ... Eu não entrei nele.

Trecho da Microsoft:

A quantidade de log para SELECT ... INTO depende do modelo de recuperação em vigor para o banco de dados. No modelo de recuperação simples ou no modelo de recuperação com registro em massa, as operações em massa são minimamente registradas. Com registro mínimo, o uso da instrução SELECT… INTO pode ser mais eficiente do que criar uma tabela e, em seguida, preencher a tabela com uma instrução INSERT

Procurando ajuda

obrigado


fonte
Qual banco de dados você está usando? Quais estruturas são as tabelas? Como você mediu que um é mais rápido que o outro?
Eu ficaria surpreso se houvesse alguma diferença em um DBMS bem escrito.
Banco de dados: servidor Sql 20005 ... e eu ouvi isso .. mesmo eu não tenho 100% de certeza ... eu estou procurando o que as outras pessoas dizem .. Como eu mencionei que alguém me disse isso ..
Foi encontrado um link que confirma que SELECT INTOpode ser registrado minimamente quando não estiver usando a Recuperação completa.
Damien_The_Unbeliever

Respostas:

10

Algumas idéias / teorias:

SELECT INTO ... permite que o RDBMS determine a ordem de classificação com base na ordem da sua tabela original. Se você inserir em uma tabela existente, pode haver uma classificação necessária para corresponder a um índice agrupado ou não clusterizado.

Sem índices - quando você SELECT INTO...sabe que o RDBMS com certeza não há índices pré-existentes para atualizar.

Sem contenção - como a tabela em que você está inserindo não existe, o SQL Server não precisa se preocupar com o bloqueio no nível de linha ou com o tratamento de contenções. Nada mais pode fazer referência à tabela criada, pois ela não existe.

Tudo isso dito, existem outras maneiras de inserir em uma tabela muito rapidamente.

  • Verifique se suas chaves de índice em cluster correspondem quando possível. Isso significa que não há classificação on-the-fly

  • Desative todos os índices não agrupados em cluster. Auto-explicativo.

  • Defina o modo de recuperação como simples e trace o sinalizador 610 para ON. Use a TABLOCKdica na tabela de destino e NOLOCKa tabela de origem.

Por exemplo, suponha que tablea e tableb tenham o mesmo índice de cluster:

INSERT INTO TableB WITH (TABLOCK)
SELECT <Columns>
FROM TableA WITH (NOLOCK)

Na minha experiência, isso é mais rápido do que usar SELECT INTO...e criar o índice clusterizado posteriormente. Observe que isso também pode funcionar em uma tabela que já possui dados, o que é um cenário muito mais útil.

EDITAR:

Aqui está um white paper fantasticamente detalhado da MS para desempenho de carregamento de dados no Sql Server 2008.

JNK
fonte
3
Resposta muito completa JNK. Além disso, quando implementado corretamente e o modelo de recuperação não estiver cheio, uma tarefa simples de fluxo de dados do SSIS pode ser mais rápida que qualquer um deles. Por quê? Ambas as opções acima emitirão um bloqueio exclusivo (a leitura é multithread, mas a gravação é single thread). Desde que um bloqueio de tabela seja usado com o adaptador de destino, o SSIS usará um bloqueio de atualização em massa (leitura e gravação são multithread).
brian