DELETE语句

2020-12-04
单表语法:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [WHERE where_condition]
    [ORDER BY ...]
    [LIMIT row_count]
多表语法:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    tbl_name[.*] [, tbl_name[.*]] ...
    FROM table_references
    [WHERE where_condition]

DELETE [LOW_PRIORITY] [QUICK] [IGNORE]
    FROM tbl_name[.*] [, tbl_name[.*]] ...
    USING table_references
    [WHERE where_condition]

如果指定了ORDER BY子句,则按指定的顺序删除行。该LIMIT子句限制了可以删除的行数。这些子句适用于单表删除,但不适用于多表删除

修饰符

LOW_PRIORITY:服务器将延迟执行,直到没有其他客户端从表中读取为止,只会影响仅使用表级锁的存储引擎(例如 MyISAM,MEMORY和 MERGE)
QUICK:对于MyISAM表,存储引擎在删除期间不会合并索引叶,这可能会加快某些类型的删除操作
IGNORE:MySQL删除行的过程中,忽略错误

注意

  • 删除时不能再子查询中引用要删除的表,但是可以使用派生表
  • DELETE支持使用PARTITION选项显式选择分区,该选项采用一个或多个分区或子分区(或两者)的逗号分隔名称列表,从中选择要删除的行。未包括在列表中的分区将被忽略。给定一个分区表t有一个分区p0,执行该语句DELETE FROM t PARTITION (p0)与ALTER TABLE t TRUNCATE PARTITION (p0)执行该表具有相同的作用; 在这两种情况下,分区p0中的所有行均被删除。
  • PARTITION可以与WHERE条件一起使用 ,在这种情况下,仅在列出的分区中的行上测试条件。例如, DELETE FROM t PARTITION (p0) WHERE c < 5 仅从条件c < 5为真的p0分区中删除行;不会检查任何其他分区中的行。
  • 如果删除包含AUTO_INCREMENT列最大值的行 ,则该值不会再用于MyISAM或InnoDB 表;如果删除表中的所有行,除InnoDB和MyISAM之外的所有存储引擎都将重新开始执行这个顺序。

从大表中删除很多数据

如果从一个大表中删除很多行,可能会超出InnoDB表的锁表大小。为了避免这个问题,或者只是为了最小化表保持锁定的时间,以下方法可能有用:

选择不删除的行到与原始表结构相同的空表中
INSERT INTO t_copy SELECT * FROM t WHERE ... ;
用于RENAME TABLE以原子方式将原始表移开,并将副本重命名为原始名称:
RENAME TABLE t TO t_old, t_copy TO t;
删除原始表:
DROP TABLE t_old;

MyISAM

  • 在MyISAM表中,删除的行在一个链表中维护,随后的插入操作重用旧的行位置。要回收未使用的空间并减小文件大小,可以使用OPTIMIZE TABLE语句或myisamchk实用程序重新组织表。OPTIMIZE TABLE更容易使用,但myisamchk更快
  • DELETE QUICK 对于将删除行的索引值替换为以后插入的行中的相似索引值的应用程序最有用。在这种情况下,删除值留下的漏洞将被重用。
{/if}