DELETE
is a DML statement that removes rows from a table.DELETE
是从表中删除行的DML语句。
A DELETE
statement can start with a WITH
clause to define common table expressions accessible within the DELETE
. DELETE
语句可以以WITH
子句开始,定义DELETE
语句中可访问的公共表表达式。See Section 13.2.15, “WITH (Common Table Expressions)”.请参阅第13.2.15节,“WITH(公共表表达式)”。
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[[AS]tbl_alias
] [PARTITION (partition_name
[,partition_name
] ...)] [WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
The DELETE
statement deletes rows from tbl_name
and returns the number of deleted rows. DELETE
语句从tbl_name
中删除行并返回删除的行数。To check the number of deleted rows, call the 要检查删除的行数,请调用第12.16节,“信息函数”中描述的ROW_COUNT()
function described in Section 12.16, “Information Functions”.ROW_COUNT()
函数。
The conditions in the optional 可选WHERE
clause identify which rows to delete. With no WHERE
clause, all rows are deleted.WHERE
子句中的条件标识要删除的行。如果没有WHERE
子句,则删除所有行。
where_condition
is an expression that evaluates to true for each row to be deleted. where_condition
是一个表达式,对于要删除的每一行,该表达式的计算结果都为true
。It is specified as described in Section 13.2.10, “SELECT Statement”.如第13.2.10节,“SELECT语句”所述。
If the 如果指定了ORDER BY
clause is specified, the rows are deleted in the order that is specified. ORDER BY
子句,则按指定的顺序删除行。The LIMIT
clause places a limit on the number of rows that can be deleted. LIMIT
子句限制可以删除的行数。These clauses apply to single-table deletes, but not multi-table deletes.这些子句适用于单表删除,但不适用于多表删除。
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]tbl_name
[.*] [,tbl_name
[.*]] ... FROMtable_references
[WHEREwhere_condition
] DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[.*] [,tbl_name
[.*]] ... USINGtable_references
[WHEREwhere_condition
]
You need the 您需要表的DELETE
privilege on a table to delete rows from it. DELETE
权限才能从中删除行。You need only the 对于任何只读取的列(如SELECT
privilege for any columns that are only read, such as those named in the WHERE
clause.WHERE
子句中指定的列),您只需要SELECT
权限。
When you do not need to know the number of deleted rows, the 当您不需要知道已删除的行数时,TRUNCATE TABLE
statement is a faster way to empty a table than a DELETE
statement with no WHERE
clause. TRUNCATE TABLE
语句比不带WHERE
子句的DELETE
语句更快地清空表。Unlike 与DELETE
, TRUNCATE TABLE
cannot be used within a transaction or if you have a lock on the table. DELETE
不同,TRUNCATE TABLE
不能在事务中使用,也不能在表上有锁的情况下使用。See Section 13.1.37, “TRUNCATE TABLE Statement” and Section 13.3.6, “LOCK TABLES and UNLOCK TABLES Statements”.参见第13.1.37节,“TRUNCATE TABLE语句”和第13.3.6节,“LOCK TABLES和UNLOCK TABLES语句”。
The speed of delete operations may also be affected by factors discussed in Section 8.2.5.3, “Optimizing DELETE Statements”.删除操作的速度也可能受到第8.2.5.3节,“优化删除语句”中讨论的因素的影响。
To ensure that a given 为了确保给定的DELETE
statement does not take too much time, the MySQL-specific LIMIT
clause for row_count
DELETE
specifies the maximum number of rows to be deleted. DELETE
语句不会花费太多时间,DELETE
的MySQL专用的LIMIT
子句指定要删除的最大行数。row_count
If the number of rows to delete is larger than the limit, repeat the 如果要删除的行数大于限制,请重复DELETE
statement until the number of affected rows is less than the LIMIT
value.DELETE
语句,直到受影响的行数小于LIMIT
值。
You cannot delete from a table and select from the same table in a subquery.不能从表中删除,也不能从子查询中的同一表中选择。
DELETE
supports explicit partition selection using the PARTITION
clause, which takes a list of the comma-separated names of one or more partitions or subpartitions (or both) from which to select rows to be dropped. DELETE
支持使用PARTITION
子句进行显式分区选择,该子句获取一个或多个分区或子分区(或两者)的逗号分隔名称列表,从中选择要删除的行。Partitions not included in the list are ignored. 不包括在列表中的分区将被忽略。Given a partitioned table 给定一个分区为t
with a partition named p0
, executing the statement DELETE FROM t PARTITION (p0)
has the same effect on the table as executing ALTER TABLE t TRUNCATE PARTITION (p0)
; in both cases, all rows in partition p0
are dropped.p0
的分区表t
,执行DELETE FROM t partition (p0)
语句与执行ALTER table t TRUNCATE partition (p0)
语句对表的影响相同;在这两种情况下,都会删除分区p0
中的所有行。
PARTITION
can be used along with a WHERE
condition, in which case the condition is tested only on rows in the listed partitions. PARTITION
可以与WHERE
条件一起使用,在这种情况下,只对列出的分区中的行测试条件。For example, 例如,DELETE FROM t PARTITION (p0) WHERE c < 5
deletes rows only from partition p0
for which the condition c < 5
is true; rows in any other partitions are not checked and thus not affected by the DELETE
.DELETE FROM t PARTITION (p0) WHERE c < 5
只从分区p0
中删除行,并要满足条件c < 5
,不检查任何其他分区中的行,因此不受DELETE
的影响。
The PARTITION
clause can also be used in multiple-table DELETE
statements. PARTITION
子句也可以用在多表DELETE
语句中。You can use up to one such option per table named in the 对于在FROM
option.FROM
选项中命名的每个表,最多可以使用一个这样的选项。
For more information and examples, see Section 24.5, “Partition Selection”.有关更多信息和示例,请参阅第24.5节“分区选择”。
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. AUTO_INCREMENT
列的最大值的行,则MyISAM
或InnoDB
表不会重用该值。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
. autocommit
模式下使用DELETE FROM
删除了表中的所有行(不用tbl_name
WHERE
子句),对于除了InnoDB
和MyISAM
之外的所有存储引擎,序列会重新开始。There are some exceptions to this behavior for InnoDB
tables, as discussed in Section 15.6.1.6, “AUTO_INCREMENT Handling in InnoDB”.InnoDB
表的这种行为有一些例外,如第15.6.1.6节,“InnoDB中的自动增量处理”所述。
For 对于MyISAM
tables, you can specify an AUTO_INCREMENT
secondary column in a multiple-column key. MyISAM
表,可以在多列键中指定AUTO_INCREMENT
的第二列。In this case, reuse of values deleted from the top of the sequence occurs even for 在这种情况下,即使对于MyISAM
tables. MyISAM
表,也会重用从序列顶部删除的值。See Section 3.6.9, “Using AUTO_INCREMENT”.请参阅第3.6.9节,“使用自动增量”。
The DELETE
statement supports the following modifiers:DELETE
语句支持以下修饰符:
If you specify the 如果指定LOW_PRIORITY
modifier, the server delays execution of the DELETE
until no other clients are reading from the table. LOW_PRIORITY
修饰符,则服务器会延迟DELETE
的执行,直到没有其他客户端正在从表中读取。This affects only storage engines that use only table-level locking (such as 这只影响仅使用表级锁定的存储引擎(如MyISAM
, MEMORY
, and MERGE
).MyISAM
、MEMORY
和MERGE
)。
For 对于MyISAM
tables, if you use the QUICK
modifier, the storage engine does not merge index leaves during delete, which may speed up some kinds of delete operations.MyISAM
表,如果使用QUICK
修饰符,则存储引擎在删除期间不会合并索引叶,这可能会加快某些类型的删除操作。
The IGNORE
modifier causes MySQL to ignore ignorable errors during the process of deleting rows. IGNORE
修饰符使MySQL在删除行的过程中忽略可忽略的错误。(Errors encountered during the parsing stage are processed in the usual manner.) (解析阶段遇到的错误将按常规方式处理。)Errors that are ignored due to the use of 由于使用IGNORE
are returned as warnings. IGNORE
而被忽略的错误将作为警告返回。For more information, see The Effect of IGNORE on Statement Execution.有关详细信息,请参阅IGNORE对语句执行的影响。
If the 如果DELETE
statement includes an ORDER BY
clause, rows are deleted in the order specified by the clause. DELETE
语句包含ORDER BY
子句,则按该子句指定的顺序删除行。This is useful primarily in conjunction with 这主要与LIMIT
. LIMIT
一起使用。For example, the following statement finds rows matching the 例如,以下语句查找与WHERE
clause, sorts them by timestamp_column
, and deletes the first (oldest) one:WHERE
子句匹配的行,按timestamp_column
对它们进行排序,并删除第一个(最早的)行:
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
ORDER BY
also helps to delete rows in an order required to avoid referential integrity violations.ORDER BY
还有助于按避免引用完整性冲突所需的顺序删除行。
If you are deleting many rows from a large table, you may exceed the lock table size for an 如果要从一个大表中删除许多行,则可能会超过InnoDB
table. InnoDB
表的锁表大小。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:DELETE
)可能会有所帮助:
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
以原子方式将原始表移开,并将副本重命名为原始名称:
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. RENAME TABLE
执行时,没有其他会话可以访问所涉及的表,因此重命名操作不受并发问题的影响。See Section 13.1.36, “RENAME TABLE Statement”.请参阅第13.1.36节,“RENAME TABLE语句”。
In 在MyISAM
tables, deleted rows are maintained in a linked list and subsequent INSERT
operations reuse old row positions. MyISAM
表中,删除的行保存在链表中,随后的INSERT
操作重用旧的行位置。To reclaim unused space and reduce file sizes, use the 要回收未使用的空间并减少文件大小,请使用OPTIMIZE TABLE
statement or the myisamchk utility to reorganize tables. OPTIMIZE TABLE
语句或myisamchk实用程序重新组织表。OPTIMIZE TABLE
is easier to use, but myisamchk is faster. OPTIMIZE TABLE
更容易使用,但myisamchk更快。See Section 13.7.3.4, “OPTIMIZE TABLE Statement”, and Section 4.6.4, “myisamchk — MyISAM Table-Maintenance Utility”.请参阅第13.7.3.4节,“优化表语句”和第4.6.4节,“myisamchk-MyISAM表维护实用程序”。
The QUICK
modifier affects whether index leaves are merged for delete operations. QUICK
修饰符会影响是否为删除操作合并索引叶。对于那些删除行的索引值被稍后插入行的类似索引值替换的应用程序,DELETE QUICK
is most useful for applications where index values for deleted rows are replaced by similar index values from rows inserted later. DELETE QUICK
最有用。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. DELETE QUICK
将不起作用。In this case, use of 在这种情况下,使用QUICK
can lead to wasted space in the index that remains unreclaimed. QUICK
可能会导致索引中未声明的空间被浪费。Here is an example of such a scenario:下面是这样一个场景的示例:
Create a table that contains an indexed 创建一个包含索引AUTO_INCREMENT
column.AUTO_INCREMENT
列的表。
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
.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
. 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. QUICK
而使用DELETE
,它们也会保持未填满状态,除非某些已删除的索引值恰好位于未填满的块内或附近的索引块中。To reclaim unused index space under these circumstances, use 要在这些情况下回收未使用的索引空间,请使用OPTIMIZE TABLE
.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
. delete QUICK
和OPTIMIZE table
可能会更快。This rebuilds the index rather than performing many index block merge operations.这将重建索引,而不是执行许多索引块合并操作。
You can specify multiple tables in a 可以在DELETE
statement to delete rows from one or more tables depending on the condition in the WHERE
clause. DELETE
语句中指定多个表,以根据WHERE
子句中的条件从一个或多个表中删除行。You cannot use 不能在多表ORDER BY
or LIMIT
in a multiple-table DELETE
. DELETE
中使用ORDER BY
或LIMIT
。The table_references
clause lists the tables involved in the join, as described in Section 13.2.10.2, “JOIN Clause”.table_references
子句列出了联接中涉及的表,如第13.2.10.2节,“联接子句”所述。
For the first multiple-table syntax, only matching rows from the tables listed before the 对于第一种多表语法,只删除FROM
clause are deleted. FROM
子句之前列出的表中的匹配行。For the second multiple-table syntax, only matching rows from the tables listed in the 对于第二种多表语法,只删除FROM
clause (before the USING
clause) are deleted. FROM
子句(在USING
子句之前)中列出的表中的匹配行。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
.t1
和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
. DELETE
语句可以使用SELECT
语句中允许的其他联接类型,例如LEFT JOIN
。For example, to delete rows that exist in 例如,要删除t1
that have no match in t2
, use a LEFT JOIN
:t1
中存在的与t2
中不匹配的行,请使用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.tbl_name
后面加.*
以与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. InnoDB
表的多表DELETE
语句,其中有外键约束,MySQL优化器可能会按照不同于表的父/子关系的顺序处理表。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.InnoDB
提供的ON DELETE
功能来相应地修改其他表。
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. DELETE
中的表别名应仅在语句的table_references
部分声明。Elsewhere, alias references are permitted 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;
Table aliases are also supported for single-table 从MySQL 8.0.16开始的单表DELETE
statements beginning with MySQL 8.0.16. DELETE
语句也支持表别名。(Bug #89410,Bug #27455809)