Mysql delete
性能
在无需知晓删除行数的情况下,相比于没有 WHERE 子句的 DELETE 语句,TRUNCATE TABLE 语句是清空表的更快方式。与 DELETE 不同,TRUNCATE TABLE 不能在事务中使用,或者如果您对表持有锁也不能使用。
为确保给定的 DELETE 语句不会花费过多时间,针对 DELETE 的 MySQL 特定的 LIMIT row_count 子句指定了要删除的最大行数。如果要删除的行数大于限制值,则重复该 DELETE 语句,直到受影响的行数小于 LIMIT 值。
自动递增列
如果删除包含 AUTO_INCREMENT 列的最大值的行,对于 MyISAM 或 InnoDB 表,该值不会被重新使用。如果在自动提交模式下使用 DELETE FROM tbl_name(没有 WHERE 子句)删除表中的所有行,则除 InnoDB 和 MyISAM 之外的所有存储引擎的序列都将重新开始。
删除顺序
如果 DELETE 语句包含 ORDER BY 子句,则按照该子句指定的顺序删除行。这主要与 LIMIT 结合使用时很有用。例如,以下语句找到与 WHERE 子句匹配的行,根据 timestamp_column 进行排序,并删除第一个(最旧的)行:
DELETE FROM somelog WHERE user = 'jcole'
ORDER BY timestamp_column LIMIT 1;
ORDER BY 还有助于按照避免参照完整性违规所需的顺序删除行。
InnoDB 表
如果从一个大型的 InnoDB 表中删除很多行,您可能会超出 InnoDB 表的锁表大小。为避免此问题,或者只是为了尽量缩短表被锁定的时间,以下策略(完全不使用 DELETE)可能会有所帮助:
1. 将不删除的行选择到一个与原始表具有相同结构的空表中:
INSERT INTO t_copy SELECT * FROM t WHERE... ;
2. 使用 RENAME TABLE 原子地将原始表移开,并将副本重命名为原始名称:
RENAME TABLE t TO t_old, t_copy TO t;
3. 删除原始表:
DROP TABLE t_old;
在 RENAME TABLE 执行时,其他会话无法访问所涉及的表,因此重命名操作不受并发问题影响。