Otimização de desempenho de inserção de tabela de servidor SQL


8

Configuração

Em um datawarehouse, estou juntando uma tabela de fatos a 20 dimensões. A tabela de fatos possui 32 milhões de linhas e 30 colunas. Esta é uma tabela temporária, portanto não preciso lidar com outros usuários que leem ou escrevem na tabela. Seleciono 10 colunas da tabela base e 20 colunas das respectivas dimensões. As tabelas de dimensões são pequenas (entre 3 e 15.000 linhas). Os campos nos quais são unidos são números inteiros e nvarchars. Eu uso uma instrução SELECT ... INTO. Não há índices nas tabelas.

A velocidade de execução desta consulta é muito lenta para ser útil.

Soluções experimentadas

Como a consulta leva muito tempo para ser processada, tentei as seguintes soluções:

  1. Divida as 20 junções em 4 junções em 5 tabelas. O desempenho da consulta permanece baixo, no entanto.
  2. Coloque índices nas colunas de chave estrangeira. Nenhuma redução significativa de tempo.
  3. Verifique se os campos da condição de junção são inteiros. Percebi um aumento de desempenho de 25%. Não é exatamente o que estou procurando.
  4. Use uma inserção na instrução em vez de selecionar em. Desempenho pior devido ao crescimento do arquivo de log, embora o banco de dados esteja no modo de recuperação simples.

Essas descobertas levaram-me a incluir o plano de execução real, que mostra que 89% do custo está na inserção da tabela . Os outros custos são 8% de varredura da tabela na tabela de fatos e 2% na correspondência de hash para as junções internas.

Questões

  1. Quais são os possíveis motivos da inserção lenta da tabela?
  2. Quais são as maneiras de identificar esse gargalo sem o plano de execução?
  3. Quais ações posso tomar para reduzir o custo da inserção da tabela?

SELECT INTO é sobre o método DML de inserção mais rápido que existe. Qual rendimento você obtém em linhas / s e MB / s? Talvez seja simplesmente perto do máximo esperado. Qual versão do servidor é essa?
usr

As porcentagens no plano real são estimativas, não as porcentagens reais. O uso de "estatísticas io" pode revelar algo importante.
James Z

Respostas:


12

Quais são os possíveis motivos da inserção lenta da tabela? Quais são as maneiras de identificar esse gargalo sem o plano de execução?

Leia Como analisar o desempenho do SQL Server , especialmente a parte sobre Analisando os tempos de espera de execução de consultas individuais .

Quais ações posso tomar para reduzir o custo da inserção da tabela?

Isso dependeria amplamente do resultado da análise de desempenho. Em primeiro lugar, verifique se a parte SELECT é o mais rápida possível. Supondo que esse problema seja a inserção totalmente registrada de thread único, algumas soluções são:


Verifique também a fragmentação interna e externa se muitas linhas espalhadas forem excluídas primeiro da tabela.
precisa

1

Abaixo está a minha experiência e pode ajudar alguém por aí.

Estávamos tentando transferir alguns dados de um banco de dados para outro, também fazendo algumas transformações no caminho. Testando a transformação, estávamos fazendo muitas inserções, corrigindo as coisas ao longo do caminho e excluindo para testar a inserção novamente. No entanto, após algumas inserções e truncamentos, nossas consultas começaram a ficar lentas e uma inserção simples começou a levar até 9 minutos, enquanto estava em execução por cerca de 3 minutos.

  1. Bem, começamos a otimizar os SELECTs primeiro. Em vez de subconsultas, usamos #tempTables. Enquanto isso agilizava um pouco as coisas, ainda não era satisfatório.
  2. O que fez toda a diferença foi a reconstrução do índice e uma atualização de estatísticas no banco de dados de destino, que levou a inserção em cerca de 2 minutos.

Portanto, tente essas duas estratégias e veja como isso funciona para você.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.