在业务场景要求高的数据库中,对于单条删除和更新操作,在 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…