Pergunta

Tive que excluir todas as linhas de uma tabela de log que continha cerca de 5 milhões de linhas.Minha tentativa inicial foi emitir o seguinte comando no analisador de consultas:

excluir do client_log

o que demorou muito.

Foi útil?

Solução

Confira tabela truncada o que é muito mais rápido.

Outras dicas

Eu descobri o TABELA TRUNCADA na referência transact-SQL do msdn.Para todos os interessados, aqui estão as observações:

TRUNCATE TABLE é funcionalmente idêntico à instrução DELETE sem nenhuma cláusula WHERE:ambos removem todas as linhas da tabela.Mas TRUNCATE TABLE é mais rápido e usa menos recursos do sistema e do log de transações que DELETE.

A instrução DELETE remove uma linha por vez e registra uma entrada no log de transações para cada linha excluída.TRUNCATE TABLE remove os dados desalocando as páginas de dados usadas para armazenar os dados da tabela, e apenas as desalocações de páginas são registradas no log de transações.

TRUNCATE TABLE remove todas as linhas de uma tabela, mas a estrutura da tabela e suas colunas, restrições, índices e assim por diante permanecem.O contador usado por uma identidade para novas linhas é redefinido para a semente da coluna.Se desejar manter o contador de identidade, use DELETE.Se você deseja remover a definição da tabela e seus dados, use a instrução DROP TABLE.

Você não pode usar TRUNCATE TABLE em uma tabela referenciada por uma restrição FOREIGN KEY;em vez disso, use a instrução DELETE sem uma cláusula WHERE.Como TRUNCATE TABLE não está registrado, ele não pode ativar um gatilho.

TRUNCATE TABLE não pode ser usado em tabelas que participam de uma visualização indexada.

Existe um mito comum de que TRUNCATE de alguma forma ignora o log de transações.

Isso é um mal-entendido e é claramente mencionado no MSDN.

Este mito é invocado em vários comentários aqui.Vamos erradicar isso juntos ;)

Para referência TABELA TRUNCADA também funciona no MySQL

esqueça truncar e excluir.mantenha as definições de sua tabela (caso queira recriá-la) e apenas use drop table.

Eu uso o método a seguir para zerar tabelas, com a vantagem adicional de me deixar com uma cópia de arquivo da tabela.

CREATE TABLE `new_table` LIKE `table`;
RENAME TABLE `table` TO `old_table`, `new_table` TO `table`;

truncate table é não Independente da plataforma SQL.Se você suspeitar que você poder alguma vez mudar de provedor de banco de dados, você pode ter medo de usá-lo.

No SQL Server você pode usar o Truncate Table comando que é mais rápido que uma exclusão normal e também usa menos recursos.Ele também redefinirá todos os campos de identidade para o valor inicial.

As desvantagens do truncate são que ele não pode ser usado em tabelas referenciadas por chaves estrangeiras e não dispara nenhum gatilho.Além disso, você não poderá reverter os dados se algo der errado.

Observe que TRUNCATE também redefinirá quaisquer teclas de incremento automático, se você as estiver usando.

Se você não deseja perder suas chaves de incremento automático, você pode acelerar a exclusão excluindo em conjuntos (por exemplo, DELETE FROM table WHERE id > 1 AND id < 10000).Isso irá acelerar significativamente e, em alguns casos, evitar que os dados sejam bloqueados.

Sim, bem, excluir 5 milhões de linhas provavelmente levará muito tempo.A única maneira potencialmente mais rápida que consigo pensar seria descartar a tabela e recriá-la.Isso só funciona, é claro, se você quiser excluir TODOS os dados da tabela.

truncar tabela client_log

é sua melhor aposta, truncar mata todo o conteúdo da tabela e dos índices e redefine todas as sementes que você possui.

A sugestão de "Descartar e recriar a tabela" provavelmente não é boa porque isso atrapalha suas chaves estrangeiras.

Você ESTÁ usando chaves estrangeiras, certo?

Se você não puder usar TRUNCATE TABLE por causa de chaves estrangeiras e/ou gatilhos, você pode considerar:

  • elimine todos os índices;
  • faça o DELETE habitual;
  • recrie todos os índices.

Isso pode acelerar um pouco o DELETE.

Estou revisando minha declaração anterior:

Você deve entender que, usando truncate, os dados serão limpos, mas nada será registrado no log de transações.Escrever para o log é o motivo pelo qual Delete levará uma eternidade em 5 milhões de linhas.Eu uso truncado frequentemente durante o desenvolvimento, mas você deve estar cauteloso em usá -lo em um banco de dados de produção, porque você não poderá reverter suas alterações.Você deve fazer um backup completo de banco de dados depois de fazer um truncado para estabelecer uma nova base para a restauração.

A declaração acima pretendia incentivá-lo a ter certeza de que entende que há diferença entre os dois.Infelizmente, está mal escrito e faz declarações não comprovadas, pois na verdade não fiz nenhum teste entre os dois.Baseia-se em declarações que ouvi de outras pessoas.

De MSDN:

A instrução Excluir remove as linhas uma de cada vez e registra uma entrada no log de transações para cada linha excluída.A tabela truncada remove os dados, revelando as páginas de dados usadas para armazenar os dados da tabela e apenas as negociações da página são registradas no log de transações.

Queria apenas dizer que existe uma diferença fundamental entre os dois e porque existe uma diferença, haverá aplicações em que um ou outro poderá ser inadequado.

DELETE * FROM table_name;

A otimização prematura pode ser perigosa.Otimizar pode significar fazer algo estranho, mas se funcionar, você pode querer tirar vantagem disso.

SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;

Para velocidade, acho que depende de ...

  • O banco de dados subjacente:Oracle, Microsoft, MySQL, PostgreSQL, outros, personalizados...

  • A tabela, seu conteúdo e tabelas relacionadas:

Pode haver regras de exclusão.Existe um procedimento para excluir todo o conteúdo da tabela?Isso pode ser otimizado para o mecanismo de banco de dados subjacente específico?Quanto nos preocupamos em quebrar coisas/dados relacionados?Executar um DELETE pode ser a maneira mais 'segura', assumindo que outras tabelas relacionadas não dependam desta tabela.Existem outras tabelas e consultas que estão relacionadas/dependem dos dados desta tabela?Se não nos importamos muito com a existência desta tabela, usar DROP pode ser um método rápido, novamente dependendo do banco de dados subjacente.

DROP TABLE table_name;

Quantas linhas estão sendo excluídas?Existem outras informações coletadas rapidamente que otimizarão a exclusão?Por exemplo, podemos saber se a tabela já está vazia?Podemos dizer se existem centenas, milhares, milhões, bilhões de linhas?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top