你习惯delete语句后带上limit吗

声明:本文基于MySQL讲解。

先不说习惯不习惯的,很多人也许会惊讶:还可以这样操作?其实,大家对这个操作比较陌生,也不奇怪。因为,学海无涯呀~

语法

这个用法的详细语法是这样的:delete from table_name where ... limit row_count。

row_count表示行数,必须是单个数字,它会告知服务器在控制命令被返回到客户端前被删除的行的最大值。从而确保一个delete语句不会占用过多的时间。

Delete语句还可以包括一个Order By子句,那样则会按照子句中指定的顺序进行删除。但是Order By子句必须与limit联用是才起作用。例如,以下子句用于查找与WHERE子句对应的行,使用age进行排序,并删除第一(年龄最大的)行:

delete from user where user_name = '马云' order by age desc limit 1;

分析一个场景

在业务场景复杂的情况下,单表删除带上limit是一个很好的习惯。

因为,我们要知道delete删除是不会释放磁盘空间的。

假如在删除执行中,第一行就命中了删除行,如果不带上limit,那么数据库还会在全表扫描之后才return,这样会很占用资源,数据量小还好说,但是如果这条表的数据量是100万条,1000万条呢,消耗的资源可想而知,而且效果还不好。如果SQL中有limit 1,那么在扫描第一行后就return了。

优点

以上面删除年龄最大的行SQL语句为例,大致有以下几个优点:

  • 降低delete的风险。加上limit row_count,最多损失row_count行数据。并且可以通过binlog找回,不会耗费多长时间,工作量也不大。

  • 避免长事务,减少其他客户端资源等待的时间。执行delete操作时,MySQL会将所有涉及的行加上写锁和Gap锁(间隙锁),如果user_name字段建立了索引,那么只锁定user_name等于‘马云’的数据,但是如果where条件的字段没建索引,那么就会扫描到主键索引上,给全表加锁,即便叫‘马云’的只有一个人

  • 减少CPU使用率。delete执行删除的数据量大时,会将CPU打满,导致后续删除越来越慢。

(0)

相关推荐