- MySQL 5.1 Reference Manual :: 12 SQL Statement Syntax :: 12.2 Data Manipulation Statements :: 12.2.2 DELETE Syntax
-
- MySQL 5.1 Reference Manual
- Preface, Notes, Licenses
- 1 General Information
- 2 Installing and Upgrading MySQL
- 3 Tutorial
- 4 MySQL Programs
- 5 MySQL Server Administration
- 6 Backup and Recovery
- 7 Optimization
- 8 Language Structure
- 9 Internationalization and Localization
- 10 Data Types
- 11 Functions and Operators
- 12 SQL Statement Syntax
- 13 Storage Engines
- 14 High Availability and Scalability
- 15 MySQL Enterprise Monitor
- 16 Replication
- 17 MySQL Cluster NDB 6.X/7.X
- 18 Partitioning
- 19 Stored Programs and Views
- 20 INFORMATION_SCHEMA Tables
- 21 Connectors and APIs
- 22 Extending MySQL
- A MySQL 5.1 Frequently Asked Questions
- B Errors, Error Codes, and Common Problems
- C MySQL Change History
- D Restrictions and Limits
- Index
- Standard Index
- C Function Index
- Command Index
- Function Index
- INFORMATION_SCHEMA Index
- Transaction Isolation Level Index
- JOIN Types Index
- Operator Index
- Option Index
- Privileges Index
- SQL Modes Index
- Status Variable Index
- Statement/Syntax Index
- System Variable Index
Single-table syntax:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM
tbl_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] FROM
tbl_name
[.*] [,tbl_name
[.*]] ... USINGtable_references
[WHEREwhere_condition
]For the single-table syntax, the
DELETE
statement deletes rows fromtbl_name
and returns a count of the number of deleted rows. This count can be obtained by calling theROW_COUNT()
function (see Section 11.11.3, “Information Functions”). TheWHERE
clause, if given, specifies the conditions that identify which rows to delete. With noWHERE
clause, all rows are deleted. If theORDER BY
clause is specified, the rows are deleted in the order that is specified. TheLIMIT
clause places a limit on the number of rows that can be deleted.For the multiple-table syntax,
DELETE
deletes from eachtbl_name
the rows that satisfy the conditions. In this case,ORDER BY
andLIMIT
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.8, “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 theSELECT
privilege for any columns that are only read, such as those named in theWHERE
clause.As stated, a
DELETE
statement with noWHERE
clause deletes all rows. A faster way to do this, when you do not need to know the number of deleted rows, is to useTRUNCATE TABLE
. However, within a transaction or if you have a lock on the table,TRUNCATE TABLE
cannot be used whereasDELETE
can. See Section 12.2.10, “TRUNCATE TABLE
Syntax”, and Section 12.3.5, “LOCK TABLES
andUNLOCK TABLES
Syntax”.If you delete the row containing the maximum value for an
AUTO_INCREMENT
column, the value is not reused for aMyISAM
orInnoDB
table. If you delete all rows in the table withDELETE FROM
(without atbl_name
WHERE
clause) inautocommit
mode, the sequence starts over for all storage engines exceptInnoDB
andMyISAM
. There are some exceptions to this behavior forInnoDB
tables, as discussed in Section 13.6.4.3, “AUTO_INCREMENT
Handling inInnoDB
”.For
MyISAM
tables, you can specify anAUTO_INCREMENT
secondary column in a multiple-column key. In this case, reuse of values deleted from the top of the sequence occurs even forMyISAM
tables. See Section 3.6.9, “UsingAUTO_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.23, “Speed of
DELETE
Statements”.In
MyISAM
tables, deleted rows are maintained in a linked list and subsequentINSERT
operations reuse old row positions. To reclaim unused space and reduce file sizes, use theOPTIMIZE TABLE
statement or the myisamchk utility to reorganize tables.OPTIMIZE TABLE
is easier to use, but myisamchk is faster. See Section 12.4.2.5, “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 ofQUICK
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 useDELETE
withoutQUICK
, 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, useOPTIMIZE TABLE
.If you are going to delete many rows from a table, it might be faster to use
DELETE QUICK
followed byOPTIMIZE TABLE
. This rebuilds the index rather than performing many index block merge operations.The MySQL-specific
LIMIT
option torow_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 givenDELETE
statement does not take too much time. You can simply repeat theDELETE
statement until the number of affected rows is less than theLIMIT
value.If the
DELETE
statement includes anORDER BY
clause, rows are deleted in the order specified by the clause. This is useful primarily in conjunction withLIMIT
. For example, the following statement finds rows matching theWHERE
clause, sorts them bytimestamp_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 useDELETE
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.33, “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 theWHERE
clause. However, you cannot useORDER BY
orLIMIT
in a multiple-tableDELETE
. Thetable_references
clause lists the tables involved in the join. Its syntax is described in Section 12.2.8.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 theFROM
clause (before theUSING
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
andt2
.The preceding examples use
INNER JOIN
, but multiple-tableDELETE
statements can use other types of join allowed inSELECT
statements, such asLEFT JOIN
. For example, to delete rows that exist int1
that have no match int2
, use aLEFT JOIN
:DELETE t1 FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
The syntax allows
.*
after eachtbl_name
for compatibility with Access.If you use a multiple-table
DELETE
statement involvingInnoDB
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 theON DELETE
capabilities thatInnoDB
provides to cause the other tables to be modified accordingly.Note
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
statement should be declared only in thetable_references
part. Elsewhere in the statement, alias references are allowed but not alias declarations.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 can lead to ambiguous statements that have unexpected results such as deleting rows from the wrong table. This is such a statement:DELETE FROM t1 AS a2 USING t1 AS a1 INNER JOIN t2 AS a2;
Before MySQL 5.1.23, alias declarations are allowed in other than the
table_references
part, but should be avoided for the reason just mentioned.Cross-database deletes are supported for multiple-table deletes, but you should be aware that in the list of tables from which to delete rows, aliases will have a default database unless one is specified explicitly. For example, if the default database is
test
, the following statement does not work because the unqualified aliasa1
has a default database oftest
:DELETE a1, a2 FROM db1.t1 AS a1 INNER JOIN db2.t2 AS a2 WHERE a1.id=a2.id;
To correctly match the alias, you must explicitly qualify it with the database of the table being aliased:
DELETE db1.a1, db2.a2 FROM db1.t1 AS a1 INNER JOIN db2.t2 AS a2 WHERE a1.id=a2.id;