Database
 sql >> Base de données >  >> RDS >> Database

Mythes relatifs aux performances :la troncation ne peut pas être annulée

Auteur invité :Derik Hammer (@SQLHammer)


Les différences entre TRUNCATE TABLE et DELETE sont souvent mal comprises. Je cherche à réfuter le mythe selon lequel TRUNCATE TABLE ne peut pas être annulé :

"TRUNCATE TABLE n'est pas enregistré et ne peut donc pas être annulé. Vous devez utiliser DELETE, s'il s'agit d'une transaction. »

Lire le manuel

L'article de la documentation en ligne sur TRUNCATE TABLE est assez descriptif :

"Supprime toutes les lignes d'une table ou des partitions spécifiées d'une table, sans enregistrer les suppressions de lignes individuelles. TRUNCATE TABLE est similaire à l'instruction DELETE sans clause WHERE; cependant, TRUNCATE TABLE est plus rapide et utilise moins de ressources système et de journal des transactions.

Le fait que TRUNCATE TABLE utilise moins ressources du journal des transactions implique qu'il écrit dans le journal des transactions dans une certaine mesure. Découvrons combien et étudions sa capacité à être annulée.

Prouvez-le

Dans un article précédent, Paul Randal en parlait avec minutie, mais j'ai pensé qu'il serait utile de fournir des repros très simples pour réfuter les deux éléments de ce mythe.

TRUNCATE TABLE peut-il être annulé ?

Prouver que TRUNCATE TABLE peut être annulé est assez simple. Je vais simplement mettre TRUNCATE TABLE dans une transaction et l'annuler.

USE demo;
BEGIN TRANSACTION;
  SELECT COUNT(*) [StartingTableRowCount] FROM [dbo].[Test];
  TRUNCATE TABLE [dbo].[Test];
  SELECT COUNT(*) [TableRowCountAfterTruncate] FROM [dbo].[Test];
ROLLBACK TRANSACTION;
SELECT COUNT(*) [TableRowCountAfterRollback] FROM [dbo].[Test];

Il y a 100 000 lignes dans le tableau et il revient à 100 000 lignes après la restauration :

TRUNCATE TABLE écrit-il dans le journal ?

En exécutant un CHECKPOINT, nous obtenons un point de départ propre. Ensuite, nous pouvons vérifier les enregistrements du journal avant et après TRUNCATE TABLE.

USE demo;
CHECKPOINT;
 
  SELECT COUNT(*) [StartingLogRowCount]
  FROM sys.fn_dblog (NULL, NULL);
 
  TRUNCATE TABLE [dbo].[Test];
 
  SELECT COUNT(*) [LogRowCountAfterTruncate]
  FROM sys.fn_dblog (NULL, NULL);

Notre commande TRUNCATE TABLE a généré 237 enregistrements de journal (au moins initialement). C'est ce qui nous permet d'effectuer une restauration et comment SQL Server enregistre la modification pour commencer.

Qu'en est-il des DELETE ?

Si DELETE et TRUNCATE TABLE écrivent dans le journal et peuvent être annulés, qu'est-ce qui les rend différents ?

Comme mentionné dans la référence BOL ci-dessus, TRUNCATE TABLE utilise moins de ressources système et de journal des transactions. Nous avons déjà observé que 237 enregistrements de journal ont été écrits pour la commande TRUNCATE TABLE. Maintenant, regardons le DELETE.

USE demo;
CHECKPOINT;
 
  SELECT COUNT(*) [StartingLogRowCount]
  FROM sys.fn_dblog (NULL, NULL);
 
  DELETE FROM [dbo].[Test];
 
  SELECT COUNT(*) [LogRowCountAfterDelete]
  FROM sys.fn_dblog (NULL, NULL);

Avec plus de 440 000 enregistrements de journal écrits pour DELETE, la commande TRUNCATE est nettement plus efficace.

Récapitulatif

TRUNCATE TABLE est une commande enregistrée et peut être annulée, avec un énorme avantage en termes de performances par rapport à un DELETE équivalent. DELETE devient important lorsque vous souhaitez supprimer moins de lignes qu'il n'en existe dans la table (puisque TRUNCATE TABLE n'accepte pas de clause WHERE). Pour des idées sur la façon de rendre les DELETE plus efficaces, consultez le post d'Aaron Bertrand, "Break large delete operations into chunks."

À propos de l'auteur

Derik est un professionnel des données et un nouveau MVP Microsoft Data Platform qui se concentre sur SQL Server. Sa passion se concentre sur la haute disponibilité, la reprise après sinistre, l'intégration continue et la maintenance automatisée. Son expérience couvre l'administration de bases de données à long terme, le conseil et les entreprises entrepreneuriales travaillant dans les secteurs de la finance et de la santé. Il est actuellement administrateur de base de données principal en charge de l'équipe des opérations de base de données au siège mondial de Subway Franchise. Lorsqu'il n'est pas à l'heure ou qu'il ne blogue pas sur SQLHammer.com, Derik consacre son temps à la #sqlfamily en tant que chef de chapitre du groupe d'utilisateurs FairfieldPASS SQL Server à Stamford, CT.