Single-table syntax:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
Multiple-table syntax:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]tbl_name
[.*] [,tbl_name
[.*]] ... FROMtable_references
[WHEREwhere_condition
]
Or:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[.*] [,tbl_name
[.*]] ... USINGtable_references
[WHEREwhere_condition
]
For the single-table syntax, the
DELETE
statement deletes rows from
tbl_name
and returns a count of the
number of deleted rows. This count can be obtained by calling the
ROW_COUNT()
function (see
Section 11.14, “Information Functions”). The
WHERE
clause, if given, specifies the
conditions that identify which rows to delete. With no
WHERE
clause, all rows are deleted. If the
ORDER BY
clause is specified, the rows are
deleted in the order that is specified. The
LIMIT
clause places a limit on the number of
rows that can be deleted.
For the multiple-table syntax,
DELETE
deletes from each
tbl_name
the rows that satisfy the
conditions. In this case, ORDER BY
and
LIMIT
cannot be used.
where_condition
is an expression that
evaluates to true for each row to be deleted. It is specified as
described in Section 12.2.9, “SELECT
Syntax”.
Currently, you cannot delete from a table and select from the same table in a subquery.
You need the DELETE
privilege on a
table to delete rows from it. You need only the
SELECT
privilege for any columns
that are only read, such as those named in the
WHERE
clause.
As stated, a DELETE
statement with
no WHERE
clause deletes all rows. A faster way
to do this, when you do not need to know the number of deleted
rows, is to use TRUNCATE TABLE
.
However, within a transaction or if you have a lock on the table,
TRUNCATE TABLE
cannot be used
whereas DELETE
can. See
Section 12.1.27, “TRUNCATE TABLE
Syntax”, and
Section 12.3.5, “LOCK TABLES
and
UNLOCK
TABLES
Syntax”.
If you delete the row containing the maximum value for an
AUTO_INCREMENT
column, the value is not reused
for a MyISAM
or InnoDB
table. If you delete all rows in the table with DELETE
FROM
(without a
tbl_name
WHERE
clause) in
autocommit
mode, the sequence
starts over for all storage engines except
InnoDB
and MyISAM
. There are
some exceptions to this behavior for InnoDB
tables, as discussed in
Section 13.6.5.3, “AUTO_INCREMENT
Handling in InnoDB
”.
For MyISAM
tables, you can specify an
AUTO_INCREMENT
secondary column in a
multiple-column key. In this case, reuse of values deleted from
the top of the sequence occurs even for MyISAM
tables. See Section 3.6.9, “Using AUTO_INCREMENT
”.
The DELETE
statement supports the
following modifiers:
If you specify
LOW_PRIORITY
, the server delays execution of theDELETE
until no other clients are reading from the table. This affects only storage engines that use only table-level locking (such asMyISAM
,MEMORY
, andMERGE
).For
MyISAM
tables, if you use theQUICK
keyword, the storage engine does not merge index leaves during delete, which may speed up some kinds of delete operations.The
IGNORE
keyword causes MySQL to ignore all errors during the process of deleting rows. (Errors encountered during the parsing stage are processed in the usual manner.) Errors that are ignored due to the use ofIGNORE
are returned as warnings.
The speed of delete operations may also be affected by factors
discussed in Section 7.2.2.3, “Speed of DELETE
Statements”.
In MyISAM
tables, deleted rows are maintained
in a linked list and subsequent
INSERT
operations reuse old row
positions. To reclaim unused space and reduce file sizes, use the
OPTIMIZE TABLE
statement or the
myisamchk utility to reorganize tables.
OPTIMIZE TABLE
is easier to use,
but myisamchk is faster. See
Section 12.4.2.4, “OPTIMIZE TABLE
Syntax”, and Section 4.6.3, “myisamchk — MyISAM Table-Maintenance Utility”.
The QUICK
modifier affects whether index leaves
are merged for delete operations. DELETE QUICK
is most useful for applications where index values for deleted
rows are replaced by similar index values from rows inserted
later. In this case, the holes left by deleted values are reused.
DELETE QUICK
is not useful when deleted values
lead to underfilled index blocks spanning a range of index values
for which new inserts occur again. In this case, use of
QUICK
can lead to wasted space in the index
that remains unreclaimed. Here is an example of such a scenario:
Create a table that contains an indexed
AUTO_INCREMENT
column.Insert many rows into the table. Each insert results in an index value that is added to the high end of the index.
Delete a block of rows at the low end of the column range using
DELETE QUICK
.
In this scenario, the index blocks associated with the deleted
index values become underfilled but are not merged with other
index blocks due to the use of QUICK
. They
remain underfilled when new inserts occur, because new rows do not
have index values in the deleted range. Furthermore, they remain
underfilled even if you later use
DELETE
without
QUICK
, unless some of the deleted index values
happen to lie in index blocks within or adjacent to the
underfilled blocks. To reclaim unused index space under these
circumstances, use OPTIMIZE TABLE
.
If you are going to delete many rows from a table, it might be
faster to use DELETE QUICK
followed by
OPTIMIZE TABLE
. This rebuilds the
index rather than performing many index block merge operations.
The MySQL-specific LIMIT
option to
row_count
DELETE
tells the server the maximum
number of rows to be deleted before control is returned to the
client. This can be used to ensure that a given
DELETE
statement does not take too
much time. You can simply repeat the
DELETE
statement until the number
of affected rows is less than the LIMIT
value.
If the DELETE
statement includes an
ORDER BY
clause, rows are deleted in the order
specified by the clause. This is useful primarily in conjunction
with LIMIT
. For example, the following
statement finds rows matching the WHERE
clause,
sorts them by timestamp_column
, and deletes the
first (oldest) one:
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
ORDER BY
may also be useful in some cases to
delete rows in an order required to avoid referential integrity
violations.
If you are deleting many rows from a large table, you may exceed
the lock table size for an InnoDB
table. To
avoid this problem, or simply to minimize the time that the table
remains locked, the following strategy (which does not use
DELETE
at all) might be helpful:
Select the rows not to be deleted into an empty table that has the same structure as the original table:
INSERT INTO t_copy SELECT * FROM t WHERE ... ;
Use
RENAME TABLE
to atomically move the original table out of the way and rename the copy to the original name:RENAME TABLE t TO t_old, t_copy TO t;
Drop the original table:
DROP TABLE t_old;
No other sessions can access the tables involved while
RENAME TABLE
executes, so the
rename operation is not subject to concurrency problems. See
Section 12.1.26, “RENAME TABLE
Syntax”.
You can specify multiple tables in a
DELETE
statement to delete rows
from one or more tables depending on the particular condition in
the WHERE
clause. However, you cannot use
ORDER BY
or LIMIT
in a
multiple-table DELETE
. The
table_references
clause lists the
tables involved in the join. Its syntax is described in
Section 12.2.9.1, “JOIN
Syntax”.
For the first multiple-table syntax, only matching rows from the
tables listed before the FROM
clause are
deleted. For the second multiple-table syntax, only matching rows
from the tables listed in the FROM
clause
(before the USING
clause) are deleted. The
effect is that you can delete rows from many tables at the same
time and have additional tables that are used only for searching:
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;
Or:
DELETE FROM t1, t2 USING t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;
These statements use all three tables when searching for rows to
delete, but delete matching rows only from tables
t1
and t2
.
The preceding examples use INNER JOIN
, but
multiple-table DELETE
statements
can use other types of join permitted in
SELECT
statements, such as
LEFT JOIN
. For example, to delete rows that
exist in t1
that have no match in
t2
, use a LEFT JOIN
:
DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
The syntax permits .*
after each
tbl_name
for compatibility with
Access.
If you use a multiple-table DELETE
statement involving InnoDB
tables for which
there are foreign key constraints, the MySQL optimizer might
process tables in an order that differs from that of their
parent/child relationship. In this case, the statement fails and
rolls back. Instead, you should delete from a single table and
rely on the ON DELETE
capabilities that
InnoDB
provides to cause the other tables to be
modified accordingly.
If you declare an alias for a table, you must use the alias when referring to the table:
DELETE t1 FROM test AS t1, test2 WHERE ...
Table aliases in a multiple-table
DELETE
should be declared only in
the table_references
part of the
statement.
Correct:
DELETE a1, a2 FROM t1 AS a1 INNER JOIN t2 AS a2 WHERE a1.id=a2.id; DELETE FROM a1, a2 USING t1 AS a1 INNER JOIN t2 AS a2 WHERE a1.id=a2.id;
Incorrect:
DELETE t1 AS a1, t2 AS a2 FROM t1 INNER JOIN t2 WHERE a1.id=a2.id; DELETE FROM t1 AS a1, t2 AS a2 USING t1 INNER JOIN t2 WHERE a1.id=a2.id;
Declaration of aliases other than in the
table_references
part of the statement
should be avoided because that can lead to ambiguous statements
that have unexpected results such as deleting rows from the wrong
table. This is such a statement:
DELETE t1 AS a2 FROM t1 AS a1 INNER JOIN t2 AS a2;
Before MySQL 5.5.3, alias declarations outside the
table_references
part of the statement
are disallowed for the USING
variant of
multiple-table DELETE
syntax. As of
MySQL 5.5.3, alias declarations outside
table_references
are disallowed for all
multiple-table DELETE
statements.
Before MySQL 5.5.3, for alias references in the list of tables
from which to delete rows in a multiple-table delete, the default
database is used unless one is specified explicitly. For example,
if the default database is db1
, the following
statement does not work because the unqualified alias reference
a2
is interpreted as having a database of
db1
:
DELETE a1, a2 FROM db1.t1 AS a1 INNER JOIN db2.t2 AS a2 WHERE a1.id=a2.id;
To correctly match an alias that refers to a table outside the default database, you must explicitly qualify the reference with the name of the proper database:
DELETE a1, db2.a2 FROM db1.t1 AS a1 INNER JOIN db2.t2 AS a2 WHERE a1.id=a2.id;
As of MySQL 5.5.3, alias resolution does not require qualification and alias references should not be qualified with the database name. Qualified names are interpreted as referring to tables, not aliases.