Se eu tiver uma tabela com muitos índices e executar uma instrução que insere linhas na tabela, o SQL Server inserirá linhas uma de cada vez ou as linhas serão inseridas usando paralelismo?
Se eu tiver uma tabela com muitos índices e executar uma instrução que insere linhas na tabela, o SQL Server inserirá linhas uma de cada vez ou as linhas serão inseridas usando paralelismo?
Antes do SQL Server 2016, uma
T-SQL INSERT
instrução individual sempre usava um plano de execução que insere linhas e mantém índices não clusterizados associados usando um único processador lógico . Isso responde a um aspecto da sua pergunta.A questão de inserir linhas ' uma de cada vez ' requer um pouco de explicação. Fundamentalmente, as modificações de dados em um
INSERT...SELECT
plano de execução sempre operam como um ou mais fluxos de linha por vez que são executados em ordem serial .Dito isso, o otimizador de consulta geralmente tem uma escolha entre duas estratégias de plano de execução:
A primeira opção significa que cada linha é inserida na tabela base e todos os índices não agrupados são atualizados em uma sequência serial, antes de passar para a próxima linha. Isso é conhecido como estratégia de inserção estreita ou por linha .
A segunda opção significa que todas as linhas são inseridas na tabela base (embora ainda uma de cada vez) antes de fazer a mesma coisa para cada índice não clusterizado, novamente em uma sequência serial. Isso é conhecido como estratégia de inserção ampla ou por índice .
O otimizador faz uma escolha baseada em custo entre estratégias estreitas e amplas para cada índice não agrupado, portanto, é bastante comum ver um plano de execução que mantém alguns índices não agrupados no mesmo operador da tabela base, enquanto outros índices são mantidos usando operadores separados .
A estratégia ampla/por índice também permite possíveis otimizações, como classificar o conjunto de linhas em ordem de chave para cada índice, a fim de promover um padrão de acesso sequencial.
Você pode encontrar mais detalhes sobre isso e exemplos de planos de execução em meu artigo de blog, Otimizando consultas T-SQL que alteram dados .
Há uma sugestão de feedback para permitir a manutenção paralela de índices não clusterizados. Foi bem recebido no Connect (e posteriormente migrou para a nova plataforma), mas a ideia ainda não foi implementada.
Embora esteja limitado a um único processador para modificações de dados,
INSERT...SELECT
pode usar paralelismo na parte do plano que identifica e cria os dados a inserir. A partir do SQL Server 2016,INSERT...SELECT
pode realizar inserções paralelas em um heap .Para obter o melhor desempenho de inserção, verifique se sua consulta atende aos critérios para operações minimamente registradas, possivelmente exigindo o sinalizador de rastreamento 610. Os detalhes podem ser encontrados no Guia de desempenho de carregamento de dados .
Você também pode querer investigar usando outros recursos do SQL Server que permitem inserções paralelas (com algumas ressalvas) usando vários processos:
T_SQL BULK INSERT
(de um arquivo)bcp
utilitárioSELECT INTO
permite paralelismo (Server 2014+), mas isso requer que a tabela não exista antes do início do processo e quaisquer índices não clusterizados teriam que ser adicionados posteriormente.Se você estiver usando o Enterprise Edition, as tabelas particionadas oferecem possibilidades adicionais para otimizar as inserções em massa. Novamente, consulte o Guia de desempenho de carregamento de dados para obter detalhes.
Artigos relacionados escritos por mim: