在业务要求高的数据库中,对于单次删除更新操作,删除更新后加limit1绝对是个好习惯。图片来自Pexels。比如删除执行,第一行命中被删除的行。如果SQL中有limit1,则返回,否则返回前进行??全表扫描。效率不言而喻。那么,我们需要养成每天执行delete时加limit的习惯吗?这是一个好习惯吗?在日常的SQL编写中,你有没有在写delete语句的时候用过下面的SQL?deletefromtwheresex=1limit100;你可能没用过。一般场景下,对于delete后是否加limit这个问题,我们是很陌生的,不知道有什么区别。今天就带大家一探究竟。记得写mark!在前。如果要清除表数据,建议直接用truncate,truncate效率比delete高很多,因为truncate不执行事务,不锁表,不会产生大量日志写入日志文件。truncatetabletable_name后立即释放磁盘空间并重置auto_increment的值。delete不会释放磁盘空间,但随后的insert会覆盖之前删除的数据。下面只讨论删除场景。首先,delete后支持limit关键字,但只支持一个参数,即[limitrow_count],用于在返回控制命令前通知服务器最多删除多少行给客户。.删除限制语法如下:delete\[low\_priority\]\[quick\]\[ignore\]fromtbl\_name\[where...\]\[orderby...\]\[limitrow\_count\]worth注意orderby必须和limit一起使用,否则会被优化。添加limitdeletefromtwheresex=1的好处;以上面的SQL为例:减少写错SQL的成本,即使你错删了,比如limit500,那么你会丢失500条数据,这不是致命的。数据可以快速恢复。为了避免长事务,MySQL会在执行delete时,对涉及到的所有行加上写锁和间隙锁(gaplocks),所有与DML语句执行相关的行都会被加锁。如果删除的数量很大,会直接影响相关业务的不可用。删除数据量大时,不加限制就容易把CPU占满,导致删除变慢。对于上面的第二点,前提是性别被索引。大家都知道加锁是基于索引的。如果sex字段没有索引,就会扫描到主键索引,所以即使只有一条sex=1的记录,也会锁表。关于deletelimit的使用,mysql大佬丁奇有个疑问:如果要删除一个表的前10000行数据,有3种方法:第一种,直接执行deletefromT限制10000;二是在一个连接中执行deletefromTlimit50020次;三是同时对20个连接执行deletefromTlimit500。你先想想,再看看几位老铁的回答:回答一,解决方案一,事务比较长,会长时间占用锁,导致其他客户端等待资源很长时间。方案二,串行化执行,将一个比较长的事务分成多个比较短的事务,每个事务占用锁的时间比较短,其他客户端等待相应资源的时间也比较短。这样的操作也意味着资源是分片使用的(每次执行使用不同的分片资源),可以提高并发性。方案三,人们为自己制造锁竞争,增加并发量。方案2相对较好,需要结合实际业务场景。答案2没有考虑访问数据表的并发性,只是简单的比较了这三种方案。第一种方案,一次占用的锁时间长,可能导致其他客户端一直在等待资源。第二种方案分为多次占用锁,串行执行,其他客户端可以在不占用锁的间隙工作。类似于现在多任务操作系统的时间片调度。每个人都是分片使用资源,不直接影响使用。第三种方案是自己创建锁竞争来强化并发。至于选择哪种方案,要结合实际场景,综合考虑各种因素,比如表的大小、并发量、业务对这张表的依赖程度等。回答3①直接删除10000可能会使交易执行时间过长。②效率较慢。每个周期都是一个新的短交易,不会锁定同一条记录。重复执行DELETE,直到受影响的行为为0。③虽然效率高,但是容易锁住同一条记录,死锁的可能性比较大。如何删除表的前10000行。很多朋友都选择了第二种方法,即:在一个连接周期内执行20次deletefromTlimit500。确实是这样,第二种方式相对来说更好一些。第一种方式(即:直接执行deletefromTlimit10000),单条语句耗时较长,加锁时间也比较长;而且大事务也会造成主从延迟。第三种方式(即:同时在20个连接中执行deletefromTlimit500),会人为造成锁冲突。这个例子对我们实践的指导意义是在删除数据的时候尽量增加limit。这样既可以控制删除数据的数量,使操作更加安全,又可以减少加锁的范围。因此,先删除后添加限制是一个值得养成的好习惯。作者:陈哈哈简介:MySQL社区非知名贡献者,擅长嫖知识;陪伴MySQL五年,致力于高性能SQL和事务锁优化的研究;路漫漫其修远兮,希望通过我的分享,让大家少踩一些坑。我是陈哈哈,一个爱笑的程序员。编辑:陶佳龙来源:转载自公众号MySQL江湖道(ID:mysql_chenhaha)
