在业务场景要求高的数据库中,对于单条删除和更新操作,在 delete 和 update 前面加 limit 1 相对是个好习惯。比方,在删除执行中,第一条就命中了删除行,如果 SQL 中有 limit 1;这时就 return 了,否则还会执行齐全表扫描才 return。效率显而易见。

那么,在日常执行 delete 时,咱们是否须要养成加 limit 的习惯呢?是不是一个好习惯呢?

在日常的 SQL 编写中,你写 delete 语句时是否用到过以下 SQL?

delete from t where sex = 1 limit 100; 

你或者没有用过,在个别场景下,咱们对 delete 后是否须要加 limit 的问题很生疏,也不知有多大区别,明天带你来理解一下,记得 mark!

写在后面,如果是清空表数据倡议间接用 truncate,效率上 truncate 远高于 delete,应为 truncate 不走事务,不会锁表,也不会生产大量日志写入日志文件;truncate table table_name 后立即开释磁盘空间,并重置 auto_increment 的值。delete 删除不开释磁盘空间,但后续 insert 会笼罩在之前删除的数据上。具体理解请跳转另一篇博文《delete、truncate、drop 的区别有哪些,该如何抉择》

上面只探讨 delete 场景,首先,delete 前面是反对 limit 关键字的,但仅反对单个参数,也就是 [limit row_count],用于告知服务器在管制命令被返回到客户端前被删除的行的最大值。

delete limit 语法如下,值得注意的是,order by 必须要和 limit 联用,否则就会被优化掉。

delete \[low\_priority\] \[quick\] \[ignore\] from tbl\_name  \[where ...\]    \[order by ...\]      \[limit row\_count\]

加 limit 的的长处:
以上面的这条 SQL 为例:

delete from t where sex = 1; 

1.升高写错 SQL 的代价,就算删错了,比方 limit 500, 那也就丢了 500 条数据,并不致命,通过 binlog 也能够很快复原数据。

2.防止了长事务,delete 执行时 MySQL 会将所有波及的行加写锁和 Gap 锁(间隙锁),所有 DML 语句执行相干行会被锁住,如果删除数量大,会间接影响相干业务无奈应用。

3.delete 数据量大时,不加 limit 容易把 cpu 打满,导致越删越慢。

针对上述第二点,前提是 sex 上加了索引,大家都晓得,加锁都是基于索引的,如果 sex 字段没索引,就会扫描到主键索引上,那么就算 sex = 1 的只有一条记录,也会锁表。

对于 delete limit 的应用,MySQL 大佬丁奇有一道题:

如果你要删除一个表外面的前 10000 行数据,有以下三种办法能够做到:

第一种,间接执行 delete from T limit 10000;
第二种,在一个连贯中循环执行 20 次 delete from T limit 500;
第三种,在 20 个连贯中同时执行 delete from T limit 500。

你先考虑一下,再看看几位老铁的答复:

Tony Du:

计划一,事务绝对较长,则占用锁的工夫较长,会导致其余客户端期待资源工夫较长。

计划二,串行化执行,将绝对长的事务分成屡次绝对短的事务,则每次事务占用锁的工夫绝对较短,其余客户端在期待相应资源的工夫也较短。这样的操作,同时也意味着将资源分片应用(每次执行应用不同片段的资源),能够进步并发性。

计划三,人为本人制作锁竞争,加剧并发量。

计划二绝对比拟好,具体还要结合实际业务场景。

肉山:

不思考数据表的拜访并发量,单纯从这个三个计划来比照的话。

第一个计划,一次占用的锁工夫较长,可能会导致其余客户端始终在期待资源。

第二个计划,分成屡次占用锁,串行执行,不占有锁的间隙其余客户端能够工作,相似于当初多任务操作系统的工夫分片调度,大家分片应用资源,不间接影响应用。

第三个计划,本人制作了锁竞争,加剧并发。

至于选哪一种计划要结合实际场景,综合思考各个因素吧,比方表的大小,并发量,业务对此表的依赖水平等。

~嗡嗡:

1.间接 delete 10000 可能使得执行事务工夫过长

2.效率慢点每次循环都是新的短事务,并且不会锁同一条记录,反复执行 DELETE 晓得影响行为 0 即可

3.效率虽高,但容易锁住同一条记录,产生死锁的可能性比拟高

怎么删除表的前 10000 行。比拟多的敌人都抉择了第二种形式,即:在一个连贯中循环执行 20 次 delete from T limit 500。的确是这样的,第二种形式是绝对较好的。

第一种形式(即:间接执行 delete from T limit 10000)外面,单个语句占用工夫长,锁的工夫也比拟长;而且大事务还会导致主从提早。

第三种形式(即:在 20 个连贯中同时执行 delete from T limit 500),会人为造成锁抵触。

这个例子对咱们实际的指导意义就是,在删除数据的时候尽量加 limit。这样不仅能够管制删除数据的条数,让操作更平安,还能够减小加锁的范畴。所以,在 delete 后加 limit 是个值得养成的好习惯。

好了,本文就带你理解这些,如果有相干疑难和好想法,请在下方留言,不便和小伙伴儿们一起探讨。

作者:_陈哈哈
https://blog.csdn.net/qq_3939...