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_countDELETE specifies the maximum number of rows to be deleted. DELETE语句不会花费太多时间,DELETE的MySQL专用的LIMIT 子句指定要删除的最大行数。row_countIf 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_nameWHERE clause) in autocommit mode, the sequence starts over for all storage engines except InnoDB and MyISAM. autocommit模式下使用DELETE FROM 删除了表中的所有行(不用tbl_nameWHERE子句),对于除了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)