SQL TRUNCATE TABLE

Par :

,le

La commande SQL TRUNCATE TABLE supprime toutes les lignes d’une table en une seule opération, sans parcourir chaque enregistrement individuellement. Contrairement à DELETE, elle ne génère pas d’entrée dans le journal des transactions pour chaque ligne supprimée, ce qui la rend nettement plus rapide sur les grandes tables. La structure de la table (colonnes, index, contraintes) reste intacte après l’opération. Pour supprimer des lignes de manière sélective, voir DELETE. Pour supprimer la table elle-même, voir DROP.

Syntaxe pour les commandes SQL TRUNCATE TABLE

TRUNCATE TABLE s’écrit en une seule ligne et prend le nom de la table cible comme seul argument. Elle nécessite le privilège ALTER sur la table — un privilège plus élevé que DELETE, qui lui ne requiert que DELETE. C’est un point important en production où les accès sont souvent restreints.

TRUNCATE TABLE nom_de_la_table;.

Certains SGBD proposent des options supplémentaires pour gérer les dépendances ou la réinitialisation des séquences. Ces variantes sont détaillées dans les sections par SGBD ci-dessous.

TRUNCATE TABLE table1, table2;
TRUNCATE TABLE parents CASCADE;  -- PostgreSQL
TRUNCATE TABLE nom_table;  -- MySQL avec auto-incrément réinitialisé

TRUNCATE vs DELETE vs DROP

Ces trois commandes suppriment des données, mais leurs effets sont très différents. DELETE parcourt les lignes une par une et peut cibler des enregistrements précis via WHERETRUNCATE vide la table entière en bloc sans possibilité de filtre. DROP détruit à la fois les données et la structure de la table.

CommandeDonnées suppriméesStructure conservéeAuto-incrément réinitialiséClause WHEREVitesse
TRUNCATE TABLEToutes✅ Oui✅ Oui❌ NonRapide
DELETEToutes ou sélection✅ Oui❌ Non✅ OuiMoyenne
DROP TABLEToutes❌ NonN/A❌ NonRapide
DELETE FROM logs WHERE id > 10;  
-- Suppression sélective ligne par ligne
TRUNCATE TABLE logs;              
-- Suppression totale en bloc, auto-incrément remis à 1
DROP TABLE logs;                  
-- Supprime données ET structure de la table

La règle pratique est simple : utiliser TRUNCATE pour vider complètement une table volumineuse (logs, caches, tables de staging), et DELETE dès qu’une condition WHERE est nécessaire.

Fonctionnement interne

TRUNCATE TABLE ne supprime pas les lignes une par une. Elle désalloue directement les blocs de stockage (appelés « extents ») que le SGBD avait réservés pour la table. C’est pourquoi l’opération est quasi instantanée même sur une table de plusieurs millions de lignes — le moteur n’a pas besoin de lire chaque enregistrement pour l’effacer.

Conséquence directe : le compteur d’auto-incrémentation est remis à zéro. Le prochain enregistrement inséré après un TRUNCATE reçoit l’identifiant 1, pas le suivant du dernier ID existant avant l’opération.

-- Avant TRUNCATE : table contenant 897 lignes, dernier id = 897
SELECT COUNT(*) FROM logs;  -- 897

TRUNCATE TABLE logs;

-- La table est vide et le compteur est réinitialisé
INSERT INTO logs (message) VALUES ('Nouveau test');
SELECT id FROM logs;  -- Résultat : id = 1, pas 898

Exemples par SGBD

MySQL

En MySQL, TRUNCATE TABLE réinitialise automatiquement le compteur AUTO_INCREMENT à 1. C’est un comportement qui diffère de DELETE FROM table sans WHERE, qui lui ne réinitialise pas le compteur. Si la table est référencée par une clé étrangère d’une autre table, MySQL bloque l’opération par défaut. Il faut alors désactiver temporairement les vérifications de clés étrangères, exécuter le TRUNCATE, puis les réactiver.

CREATE TABLE logs (
    id      INT AUTO_INCREMENT PRIMARY KEY,
    message VARCHAR(100)
);
INSERT INTO logs (message) VALUES ('Erreur connexion');

-- Vider la table : AUTO_INCREMENT repart à 1
TRUNCATE TABLE logs;

-- Si une clé étrangère bloque l'opération :
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE logs;
SET FOREIGN_KEY_CHECKS = 1;

PostgreSQL

PostgreSQL ajoute deux options utiles absentes de MySQL. RESTART IDENTITY remet à zéro la séquence SERIAL associée à la colonne d’identifiant — sans cette option, la séquence continue là où elle s’était arrêtée avant le TRUNCATECASCADE propage l’opération aux tables qui référencent la table cible via une clé étrangère. Sans CASCADE, PostgreSQL refuse le TRUNCATE si des dépendances existent et retourne une erreur explicite.

CREATE TABLE logs (
    id      SERIAL PRIMARY KEY,
    message VARCHAR(100)
);
INSERT INTO logs (message) VALUES ('Erreur connexion');

-- Vider + réinitialiser la séquence + propager aux tables dépendantes
TRUNCATE TABLE logs RESTART IDENTITY CASCADE;

-- Vérification : la séquence repart bien à 1
INSERT INTO logs (message) VALUES ('Test post-truncate');
SELECT id FROM logs;  -- Résultat : id = 1

SQL Server

SQL Server réinitialise le compteur IDENTITY après un TRUNCATE, comme MySQL. En revanche, il bloque l’opération si une contrainte de clé étrangère active pointe vers la table cible, même si les tables enfants sont vides. Pour contourner cela, il faut désactiver la contrainte avant l’opération, puis la réactiver.

CREATE TABLE logs (
    id      INT IDENTITY(1,1) PRIMARY KEY,
    message VARCHAR(100)
);
INSERT INTO logs (message) VALUES ('Erreur connexion');

-- Vider la table : IDENTITY repart à 1
TRUNCATE TABLE logs;

-- Si une contrainte de clé étrangère bloque :
ALTER TABLE commandes NOCHECK CONSTRAINT fk_logs;
TRUNCATE TABLE logs;
ALTER TABLE commandes CHECK CONSTRAINT fk_logs;

Oracle

Oracle propose deux options pour gérer l’espace disque libéré après le TRUNCATEDROP STORAGE libère définitivement les blocs alloués et les rend disponibles pour d’autres objets de la base. REUSE STORAGE conserve les blocs réservés à la table, ce qui accélère les insertions suivantes si la table est rapidement reremplie — cas typique des tables de staging ou de cache.

-- Libère l'espace disque (comportement par défaut)
TRUNCATE TABLE logs DROP STORAGE;

-- Conserve les blocs pour réutilisation immédiate
TRUNCATE TABLE logs REUSE STORAGE;

Bonnes pratiques en production

Avant d’exécuter un TRUNCATE en production, il est indispensable d’identifier les tables qui référencent la table cible via des clés étrangères. Une erreur de dépendance en production peut bloquer une opération critique. La requête suivante liste ces contraintes dans la majorité des SGBD compatibles avec information_schema.

SELECT constraint_name, table_name
FROM information_schema.table_constraints
WHERE table_name = 'logs';

Si les données peuvent être utiles ultérieurement (audit, débogage), il est prudent d’en faire une copie avant l’opération. Cette sauvegarde ne prend que quelques secondes sur des tables de taille raisonnable.

-- Sauvegarde avant TRUNCATE
CREATE TABLE logs_backup AS SELECT * FROM logs;

-- Puis vider la table originale
TRUNCATE TABLE logs;

Enfin, sur les tables de logs ou de cache vidées régulièrement, il est recommandé d’automatiser l’opération via un job planifié plutôt que de l’exécuter manuellement. Cela réduit le risque d’oubli et garantit des performances constantes.

Erreurs courantes

-- ❌ Clé étrangère active qui bloque l'opération (SQL Server / PostgreSQL)
TRUNCATE TABLE clients;
-- Erreur : des lignes dans "commandes" référencent "clients"

-- ✅ PostgreSQL : propager avec CASCADE
TRUNCATE TABLE clients CASCADE;

-- ✅ MySQL : désactiver les vérifications temporairement
SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE TABLE clients;
SET FOREIGN_KEY_CHECKS = 1;
sql-- ❌ Tentative d'utiliser WHERE avec TRUNCATE
TRUNCATE TABLE logs WHERE date_log < '2025-01-01';
-- Erreur de syntaxe : TRUNCATE ne supporte pas WHERE

-- ✅ Utiliser DELETE pour une suppression conditionnelle
DELETE FROM logs WHERE date_log < '2025-01-01';

Sources: Postgresql, MySql