Le moyen le plus rapide de supprimer toutes les données d'une grande table

StackOverflow https://stackoverflow.com/questions/64117

  •  09-06-2019
  •  | 
  •  

Question

J'ai dû supprimer toutes les lignes d'une table de journal contenant environ 5 millions de lignes. Mon essai initial consistait à exécuter la commande suivante dans l’analyseur de requêtes:

supprimer de client_log

qui a pris très longtemps.

Était-ce utile?

La solution

Découvrez la tronquer la table , qui est beaucoup plus rapide.

Autres conseils

J'ai découvert le TRUNCATE TABLE dans la référence msdn transact-SQL. Pour tous les intéressés, voici les remarques:

TRUNCATE TABLE est fonctionnellement identique à l’instruction DELETE sans clause WHERE: toutes les deux suppriment toutes les lignes de la table. Mais TRUNCATE TABLE est plus rapide et utilise moins de ressources système et de journal de transactions que DELETE.

L'instruction DELETE supprime les lignes une à une et enregistre une entrée dans le journal des transactions pour chaque ligne supprimée. TRUNCATE TABLE supprime les données en désallouant les pages de données utilisées pour stocker les données de la table. Seules les désallocations de pages sont enregistrées dans le journal des transactions.

TRUNCATE TABLE supprime toutes les lignes d'une table, mais la structure de la table et ses colonnes, contraintes, index, etc. restent. Le compteur utilisé par une identité pour les nouvelles lignes est réinitialisé à la valeur de départ pour la colonne. Si vous souhaitez conserver le compteur d'identité, utilisez plutôt DELETE. Si vous souhaitez supprimer la définition de table et ses données, utilisez l'instruction DROP TABLE.

Vous ne pouvez pas utiliser TRUNCATE TABLE sur une table référencée par une contrainte FOREIGN KEY; à la place, utilisez l’instruction DELETE sans clause WHERE. Comme TRUNCATE TABLE n’est pas enregistré, il ne peut pas activer de déclencheur.

TRUNCATE TABLE ne peut pas être utilisé sur les tables participant à une vue indexée.

Il existe un mythe courant selon lequel TRUNCATE ignore en quelque sorte le journal des transactions.

Ceci est un malentendu et est clairement mentionné dans MSDN.

Ce mythe est invoqué dans plusieurs commentaires ici. Éliminons-le ensemble;)

Pour référence, TRUNCATE TABLE fonctionne également sur MySQL

oubliez tronquer et supprimer. conservez vos définitions de table (au cas où vous voudriez la recréer) et utilisez simplement drop table.

J'utilise la méthode suivante pour mettre à zéro les tables, avec l'avantage supplémentaire de me laisser une copie d'archive de la table.

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

truncate table n'est pas indépendant de la plate-forme SQL. Si vous pensez que vous pourriez changer de fournisseur de base de données, vous pouvez vous méfier de l'utiliser.

Sur SQL Server, vous pouvez utiliser la commande Truncate Table qui est plus rapide qu’une suppression classique et utilise également moins de ressources. Il réinitialisera également tous les champs d'identité sur la valeur de départ.

Tronquer a pour inconvénient de ne pas pouvoir être utilisé sur des tables référencées par des clés étrangères et de ne déclencher aucun déclencheur. De plus, vous ne pourrez pas restaurer les données en cas de problème.

Notez que TRUNCATE réinitialisera également toutes les clés à incrémentation automatique, si vous les utilisez.

Si vous ne souhaitez pas perdre vos clés à incrémentation automatique, vous pouvez accélérer la suppression en supprimant des ensembles (par exemple, la table DELETE FROM WHERE id > 1 ET id < 10000). Cela accélérera considérablement et empêchera dans certains cas le verrouillage des données.

Oui, supprimer cinq millions de lignes prendra probablement beaucoup de temps. Le seul moyen potentiellement plus rapide que je puisse imaginer serait de laisser tomber la table et de la recréer. Cela ne fonctionne bien entendu que si vous souhaitez supprimer TOUTES les données du tableau.

tronquer la table client_log

est votre meilleur choix, tronquer tue tout le contenu de la table et des index et réinitialise les graines que vous avez aussi.

La suggestion de " supprimer et recréer la table " n’est probablement pas un bon choix car cela gaffe vos clés étrangères.

Vous utilisez des clés étrangères, n'est-ce pas?

Si vous ne pouvez pas utiliser TRUNCATE TABLE en raison de clés étrangères et / ou de déclencheurs, vous pouvez envisager de:

  • supprimer tous les index;
  • faire le DELETE habituel;
  • recréez tous les index.

Ceci peut accélérer quelque peu la suppression.

Je révise ma déclaration précédente:

  

Vous devriez comprendre qu'en utilisant   TRUNCATE les données seront effacées mais   rien ne sera connecté au   journal des transactions. Écrire dans le journal   C’est pourquoi DELETE prendra une éternité 5   millions de lignes. J'utilise souvent TRUNCATE   pendant le développement, mais vous devriez être   Méfiez-vous de l'utiliser sur une production   base de données parce que vous ne pourrez pas   annuler vos modifications. Vous devriez   faire immédiatement une base de données complète   sauvegarde après avoir fait un TRUNCATE à   établir une nouvelle base pour la restauration.

La déclaration ci-dessus était destinée à vous inciter à vous assurer de bien comprendre qu'il existe une différence entre les deux. Malheureusement, il est mal écrit et fait des déclarations non étayées car je n’ai pas fait de test moi-même entre les deux. Il est basé sur des déclarations que j'ai entendues par d'autres personnes.

De MSDN :

  

L'instruction DELETE supprime les lignes une   à la fois et enregistre une entrée dans le   journal des transactions pour chaque ligne supprimée.   TRUNCATE TABLE supprime les données par   désallocation des pages de données utilisées pour   stocker les données de la table, et seulement le   les désallocations de pages sont enregistrées dans le   journal des transactions.

Je voulais juste dire qu'il existe une différence fondamentale entre les deux et, parce qu'il y a une différence, il y aura des applications où l'une ou l'autre peut être inappropriée.

DELETE * FROM table_name;

Une optimisation prématurée peut être dangereuse. Optimiser peut vouloir dire faire quelque chose de bizarre, mais si cela fonctionne, vous voudrez peut-être en profiter.

SELECT DbVendor_SuperFastDeleteAllFunction(tablename, BOZO_BIT) FROM dummy;

Pour la vitesse, je pense que cela dépend de ...

  • La base de données sous-jacente: Oracle, Microsoft, MySQL, PostgreSQL, autres, personnalisée ...

  • La table, son contenu et les tables connexes:

Il peut y avoir des règles de suppression. Existe-t-il une procédure permettant de supprimer tout le contenu du tableau? Cela peut-il être optimisé pour le moteur de base de données spécifique sous-jacent? À quel point nous soucions-nous de casser des choses / des données associées? Effectuer un DELETE peut être la méthode la plus "sûre" en supposant que les autres tables associées ne dépendent pas de cette table. Existe-t-il d'autres tables et requêtes liées / dépendantes des données contenues dans cette table? Si nous ne nous soucions pas de la présence de cette table, utiliser DROP peut s’avérer une méthode rapide, qui dépend également de la base de données sous-jacente.

DROP TABLE table_name;

Combien de lignes sont supprimées? Existe-t-il d'autres informations rapidement glanées qui optimiseront la suppression? Par exemple, pouvons-nous savoir si la table est déjà vide? Peut-on savoir s’il existe des centaines, des milliers, des millions, des milliards de lignes?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top