Hook: Interviewers like TRUNCATE because it looks tiny, but it tests big ideas: speed, locks, rollback, and foreign keys.
Question: What does TRUNCATE do in SQL?
Answer: TRUNCATE empties a whole table at once. It is usually much faster than DELETE because the database does not visit every row one by one. You cannot filter it with WHERE, and details like identity reset or rollback depend on the database engine.
Interview-Ready Answer: I use TRUNCATE when I need to clear every row from a table quickly. Compared with DELETE, it usually does less row-by-row work, so it is faster on large tables and creates less logging. The two things I always check are foreign keys and engine-specific behavior, because TRUNCATE can fail on referenced tables and rollback or identity reset is not identical across databases.
TRUNCATE TABLE is the fast way to remove all rows from a table. Think of it as a table reset, not a search-and-delete. Most interviewers treat it like a DDL-style operation because it changes the table's storage and metadata rather than editing rows one by one. Metadata means the database's stored information about the table, such as its definition, counters, and internal storage state.
TRUNCATE, a rollback can undo it; in others, it may cause an implicit commit.With DELETE, the engine typically visits each matching row, removes it, updates indexes, and writes more log records. That makes the cost roughly O(n) for n rows. TRUNCATE is usually close to O(1) with respect to row count because it changes storage metadata instead of deleting rows one by one. On a table with 10 million rows, TRUNCATE is often milliseconds to a few hundred milliseconds, while DELETE can take seconds or minutes and produce much larger logs.
| Feature | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| Removes some rows | Yes, with WHERE | No | No |
| Removes all rows | Yes | Yes | Yes, plus table |
| Keeps table | Yes | Yes | No |
| Row-by-row work | Usually yes | Usually no | No |
| Identity reset | Usually no | Often yes or optional | N/A |
Key takeaway: DELETE is for selective removal, TRUNCATE is for emptying a whole table, and DROP is for removing the table itself.
TRUNCATE is transactional, supports RESTART IDENTITY, and can use CASCADE for related tables.TRUNCATE is often implemented like a drop-and-recreate operation and usually causes an implicit commit.TRUNCATE TABLE resets identity by default, but it is blocked by foreign key references unless those references are removed first.WHERE to TRUNCATE.CASCADE option.DELETE triggers.Real-world story: Imagine a checkout service that keeps a temporary cart_snapshot_staging table for nightly batch jobs. A small cleanup script uses TRUNCATE to clear the table before loading fresh data. One day a teammate adds a new audit table with a foreign key pointing to that staging table, and the cleanup job starts failing with an error like “cannot truncate a table referenced in a foreign key constraint.” The pipeline does not clear the staging data, the batch job retries, logs fill up, and the next morning dashboards show stale cart counts. The bug is not the speed of TRUNCATE; it is assuming every table can be truncated in isolation.
-- PostgreSQL example: demonstrates the main idea, a foreign-key failure path,
-- transactional rollback, and identity reset after a successful TRUNCATE.
DROP TABLE IF EXISTS order_items;
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
order_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_name TEXT NOT NULL
);
CREATE TABLE order_items (
item_id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
order_id INTEGER NOT NULL REFERENCES orders(order_id),
sku TEXT NOT NULL
);
INSERT INTO orders (customer_name) VALUES ('Ava'), ('Ben');
INSERT INTO order_items (order_id, sku)
VALUES (1, 'SKU-1'), (2, 'SKU-2');
-- Baseline: prove the tables are populated.
SELECT 'before truncate' AS phase, COUNT(*) AS orders_count FROM orders;
SELECT 'before truncate' AS phase, COUNT(*) AS items_count FROM order_items;
-- Edge case: truncating only the parent table fails because the child table still
-- references it. We catch the error so the script can continue.
DO $$
BEGIN
BEGIN
TRUNCATE TABLE orders;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Expected failure: %', SQLERRM;
END;
END
$$;
-- Edge case: in PostgreSQL, TRUNCATE is transactional, so a rollback undoes it.
BEGIN;
TRUNCATE TABLE order_items, orders RESTART IDENTITY;
ROLLBACK;
-- After rollback, the original rows are still there.
SELECT 'after rollback' AS phase, COUNT(*) AS orders_count FROM orders;
SELECT 'after rollback' AS phase, COUNT(*) AS items_count FROM order_items;
-- Correct usage: truncate both related tables together and restart identities.
TRUNCATE TABLE order_items, orders RESTART IDENTITY;
-- The identity counter starts from 1 again because of RESTART IDENTITY.
INSERT INTO orders (customer_name) VALUES ('Cara');
SELECT * FROM orders ORDER BY order_id;
SELECT * FROM order_items ORDER BY item_id;Follow-up & Tricky Questions:
TRUNCATE be rolled back? In PostgreSQL, yes, if it runs inside a transaction. In some other databases, it causes an implicit commit, so the answer depends on the engine.TRUNCATE fire DELETE triggers? Usually not row-level DELETE triggers, because rows are not deleted one by one. Some databases have special statement-level trigger behavior, so you must know the dialect.TRUNCATE reset identity or auto-increment? Often yes, or it has an option to do so, but that is database-specific. In PostgreSQL you can say RESTART IDENTITY; in other systems the syntax is different.CASCADE where supported, or choose DELETE instead.TRUNCATE over DELETE? Use it when you need the entire table empty, you do not need a row filter, and you want the faster metadata-level reset.TRUNCATE always faster? Usually on big tables, but not always worth it if you only need a few rows removed, or if the lock and dependency checks outweigh the savings.WHERE with TRUNCATE? No. That is the simplest gotcha: TRUNCATE is all-or-nothing for the table.Common Mistakes:
TRUNCATE is just a faster DELETE. Correction: it is faster because it changes storage metadata and usually skips row-by-row work.WHERE is not allowed. Correction: if you need to remove only some rows, use DELETE.Memory Hook: DELETE is a broom that sweeps one piece at a time; TRUNCATE is dumping out the whole trash bag and replacing the bag liner.
Cheat Sheet:
TRUNCATE removes all rows from a table.WHERE, no row-by-row delete.DELETE.CASCADE.Practice Tasks:
DELETE FROM table and TRUNCATE TABLE table.