Melhorar a velocidade de exclusão do SQL Server

12

Temos um enorme banco de dados de produção, seu tamanho é de cerca de 300 GB. Existe alguma abordagem para melhorar o desempenho de uma consulta de exclusão? No momento, a velocidade de exclusão está entre 1 e 10k por minuto, é muito lenta para nós.

Comunidade
fonte
2
1000 linhas por minuto parece extremamente lento. Você está enfrentando um bloqueio? Ou é tão lento selecionar as linhas também, o que sugere uma necessidade de índice?
James Z
Provavelmente você precisa criar um índice para cobrir seus critérios de exclusão.
Ginden 27/05
6
Não há detalhes suficientes para fornecer uma resposta. Qual consulta você executa? Você tem índices nas colunas de critérios envolvidas (se houver)? Você tem gatilhos ao excluir? ...
Sébastien Sevrin
3
Você está tentando excluir um bilhão de linhas por vez? É possível que você esteja aguardando o crescimento automático após o crescimento automático após o crescimento automático? (É mais do que provável que seja uma atividade de log em que você esteja aguardando, não a atividade de exclusão real.) Veja este artigo ...
Aaron Bertrand
3
Além disso. Alguma restrição de chave estrangeira? Forneça definição completa da tabela, consulta e plano de execução.
Martin Smith

Respostas:

20

Se você estiver tentando excluir um grande número de linhas em uma única instrução, é provável que esteja aguardando a atividade de log. Então você pode:

  1. Verifique se o seu log é dimensionado adequadamente para que os eventos de crescimento não o atrapalhem. Com os padrões, seu log provavelmente está começando em 1 MB com 10% de crescimento. Eventos de crescimento são caros e, se você estiver registrando até 10 GB de exclusões, isso destruirá o desempenho não apenas agora, mas também no futuro (devido ao que isso faz com as VLFs).
  2. Se você estiver excluindo toda a tabela, use TRUNCATEou DROP/ CREATE.
  3. Se você estiver excluindo grande parte da tabela, use SELECT INTOpara colocar os dados que deseja manter em outra tabela e, em seguida TRUNCATE, mova a pequena parte para trás. (Ou simplesmente solte a tabela antiga, renomeie a nova e aplique restrições / permissões etc.)
  4. Minimize o impacto do log em primeiro lugar, excluindo os dados em partes, em vez de todos de uma vez. Veja este artigo . Você também pode considerar mudar temporariamente para a recuperação simples temporariamente, para que você apenas tenha que CHECKPOINTlimpar o log em vez de fazer backups de log, mas precisará restaurá -lo e fazer um novo backup completo para reiniciar a cadeia de logs .
Aaron Bertrand
fonte
+1, para um excelente artigo. Isso me ajudou no passado a fazer com que nossos desenvolvedores entendessem a operação de exclusão quando eles continuavam nos alcançando em busca de lentidão e crescimento no arquivo de log.
KASQLDBA
Além disso, se houver índices desnecessários, soltá-los aumentará a velocidade de exclusão. Novamente, se você excluir todos ou quase todos os dados, largar todos os índices primeiro e criá-los novamente depois pode ter um bom impacto.
quer
3
O @ Tony que solta o índice também precisa ser registrado (assim como o cria), portanto pode ser apenas uma questão de quando você deseja pagar esse custo. Sem testar, não estou convencido de que haja uma enorme vantagem para o cenário de exclusão (como haveria para inserção / atualização), a menos que você tenha índices que não será mantido posteriormente.
Aaron Bertrand
A desativação temporária das restrições do FK pode melhorar a consulta?
Lev Z
3

Há alguma dica, mas qual versão você está usando? É edição empresarial? De qualquer forma:

  1. Se possível, mova o log de transações para um disco mais rápido
  2. Analise o onde . Ele usará um índice para identificar registros a serem excluídos? Caso contrário, você pode adicionar um índice?
  3. Você tem algum índice na tabela que pode soltar? Se sim, largue-os.
  4. Você tem chaves estrangeiras em relação a esta tabela? Isso pode realmente atrasar sua exclusão.
  5. Se você possui uma edição corporativa e o gargalo é a E / S de disco, uma compactação no nível da linha pode ajudar um pouco (ou não, dependendo dos dados)
  6. Você pode particionar a tabela? Índices locais e queda de partições podem ser mais rápidos.
  7. Investigue onde está o gargalo por meio do monitor de atividades.

Adicione detalhes, quando você trabalha com um grande banco de dados, não há uma única resposta válida.

user_0
fonte
0

Você deve tentar excluí-los pedaço por pedaço, provavelmente excluindo em loop, cada iteração de exclusão é sua própria transação e, em seguida, limpando o log no final de cada iteração de loop.

Além disso, você precisaria encontrar o número que usará como valor no chunk para excluir os registros. Exige um teste completo, seria melhor se você pudesse testar primeiro o valor da parte no UAT.

Para saber como proceder, remeta para Quebrar grandes operações de exclusão em pedaços

KASQLDBA
fonte
0

A exclusão pode ser lenta se a tabela grande tiver chave estrangeira recursiva.

nesse caso, encontre tempo oportuno, desative os serviços dependentes, desabilite a chave estrangeira recursiva, execute uma exclusão massiva e restaure a chave estrangeira novamente.

obratim
fonte
esse foi exatamente o meu caso. É um pouco arriscado desativar o contraint, mas a exclusão passou de 1 linha / seocnd para 500 / segundo
Jurion
0

Adicionando mais alguns pontos ...

  1. Tente verificar se o predicado tem índice e também veja as estatísticas.
  2. Se você estiver excluindo um grande número de linhas e também não desejar a opção de tabela temporária. Vá para a tablockopção.
  3. Veja se você tem algum gatilho, especificamente após excluir gatilhos.

Para obter mais ajuda, poste a consulta que você está usando, as informações da tabela mais as informações de bloqueio.

TheGameiswar
fonte