DELETE removes one or many rows from a MySQL table based on an optional condition.
DELETE lets you remove selected rows while TRUNCATE wipes the whole table. Use DELETE when you need precision and want to retain table structure, permissions, and auto-increment values.
Run DELETE FROM table_name WHERE condition;
. Omitting WHERE
deletes every row, so always double-check the filter before execution.
Target the row with a unique identifier. For example: DELETE FROM Customers WHERE id = 17;
. Only the customer with id 17 disappears; other data remains intact.
Combine date logic with DELETE
: DELETE FROM Orders WHERE order_date < NOW() - INTERVAL 1 YEAR;
. This cleans historical orders while keeping recent transactions.
First run the same SELECT
query with your WHERE
clause to preview affected rows. After confirming, switch SELECT
to DELETE
.
Yes—use DELETE t1, t2 FROM ... JOIN ... WHERE ...
. MySQL allows multi-table deletes to keep child tables in sync, reducing round-trips.
Either set ON DELETE CASCADE
in the foreign key or delete child rows first. Attempting to delete parent rows without handling children triggers a constraint error.
1) Always back up data. 2) Use transactions (START TRANSACTION ... COMMIT
) so you can ROLLBACK
on mistakes. 3) Batch large deletes with LIMIT
to avoid long locks and replication lag.
Only from backups or binary logs. MySQL lacks an undo command after COMMIT. Plan ahead by enabling point-in-time recovery.
DELETE removes rows but leaves AUTO_INCREMENT unchanged. Use ALTER TABLE ... AUTO_INCREMENT = 1 after deleting all rows if you need to reseed.
InnoDB marks pages as reusable; actual file size stays. Run OPTIMIZE TABLE or TRUNCATE to reclaim physical space.
Append ORDER BY pk, LIMIT 1000 inside a loop. Smaller batches shorten lock time and let replication keep up.