点击上方 好好学java ,选择 星标 公众号

重磅资讯、干货,第一时间送达

今日推荐:又一程序员进了ICU:压垮一个家庭,一张结算单就够

个人原创100W+访问量博客:点击前往,查看更多

在业务场景要求高的数据库中,对于单条删除和更新操作,在 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 场景,首先,delete 后面是支持 limit 关键字的,但仅支持单个参数,也就是 [limit row_count],用于告知服务器在控制命令被返回到客户端前被删除的行的最大值。

delete limit 语法如下:delete [low_priority] [quick] [ignore] from tbl_name [where ...] [order by ...] [limit row_count]

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

加 limit 的的优点

delete from t where sex = 1;

以上面的这条 SQL 为例:

  • 降低写错 SQL 的代价,就算删错了,比如 limit 500,那也就丢了 500 条数据,并不致命,通过 binlog 也可以很快恢复数据。

  • 避免了长事务,delete 执行时 MySQL 会将所有涉及的行加写锁和 Gap 锁(间隙锁),所有 DML 语句执行相关行会被锁住,如果删除数量大,会直接影响相关业务无法使用。

  • 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。

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

回答一

方案一,事务相对较长,则占用锁的时间较长,会导致其他客户端等待资源时间较长。

方案二,串行化执行,将相对长的事务分成多次相对短的事务,则每次事务占用锁的时间相对较短,其他客户端在等待相应资源的时间也较短。

这样的操作,同时也意味着将资源分片使用(每次执行使用不同片段的资源),可以提高并发性。方案三,人为自己制造锁竞争,加剧并发量。

方案二相对比较好,具体还要结合实际业务场景。

回答二

不考虑数据表的访问并发量,单纯从这个三个方案来对比的话。

第一个方案,一次占用的锁时间较长,可能会导致其他客户端一直在等待资源。第二个方案,分成多次占用锁,串行执行,不占有锁的间隙其他客户端可以工作,类似于现在多任务操作系统的时间分片调度,大家分片使用资源,不直接影响使用。第三个方案,自己制造了锁竞争,加剧并发。

至于选哪一种方案要结合实际场景,综合考虑各个因素吧,比如表的大小,并发量,业务对此表的依赖程度等。

回答三

①直接 delete 10000 可能使得执行事务时间过长。

②效率慢点每次循环都是新的短事务,并且不会锁同一条记录,重复执行 DELETE 知道影响行为 0 即可。

③效率虽高,但容易锁住同一条记录,发生死锁的可能性比较高。

怎么删除表的前 10000 行。比较多的朋友都选择了第二种方式,即:在一个连接中循环执行 20 次 delete from T limit 500。

确实是这样的,第二种方式是相对较好的。

第一种方式(即:直接执行 delete from T limit 10000)里面,单个语句占用时间长,锁的时间也比较长;而且大事务还会导致主从延迟。

第三种方式(即:在 20 个连接中同时执行 delete from T limit 500),会人为造成锁冲突。

这个例子对我们实践的指导意义就是,在删除数据的时候尽量加 limit。这样不仅可以控制删除数据的条数,让操作更安全,还可以减小加锁的范围。

所以,在 delete 后加 limit 是个值得养成的好习惯。

作者:陈哈哈 简介:MySQL 社区的非著名贡献者,善于白嫖知识;陪伴 MySQL 五年,致力于高性能 SQL、事务锁优化方面的研究;长路漫漫,希望通过自己的分享让大家少踩一些坑。我是陈哈哈,一个爱笑的程序员。编辑:陶家龙 出处:转载自公众号 MySQL 江湖路(ID:mysql_chenhaha)

原创电子书

历时整整一年总结的 Java 面试 + Java 后端技术学习指南,这是本人这几年及校招的总结,各种高频面试题已经全部进行总结,按照章节复习即可,已经拿到了大厂offer。

原创思维导图

扫码或者微信搜 程序员的技术圈子 回复 面试 领取原创电子书和思维导图。

CTO说了,delete后不加limit,直接滚蛋!相关推荐

  1. delete后加 limit是个好习惯么 !

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:_陈哈哈 https://blog.csdn.net ...

  2. delete后加 limit是个好习惯么 ?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 来源:r6d.cn/vegm 在业务场景要求高的数据库中,对于单条删除和更 ...

  3. delete 后加 limit

    在业务场景要求高的数据库中,对于单条删除和更新操作,在 delete 和 update 后面加 limit 1 绝对是个好习惯.比如,在删除执行中,第一条就命中了删除行,如果 SQL 中有 limit ...

  4. delete后加 limit是个好习惯么

    小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL专栏目录 | 点击这里 在业务场景要求高的数据库中,对于单条删除和更新操作,在delete和update后面加limit 1绝对是个好习惯. ...

  5. C++两个 delete 后的问题 野指针

    最近在网上看到两个关于指针 delete 后的问题.第一种情况: 1 2 3 int* p = new int; delete p; delete p;// p为什么能delete两次,而程序运行的时 ...

  6. mysql 释放空间_07_MySQL delete后释放存储空间

    CREATE TABLE `wkj_Score` ( `Id` int(10) NOT NULL AUTO_INCREMENT COMMENT '编号', `Stu_id` int(10) NOT N ...

  7. 有史以来最会写代码的农民诞生!腾讯元老、上市公司CTO赚够钱后辞职!到安徽农村隐居,亲手建造200亩农场!...

    财富自由之后你想过什么生活? 腾讯元老魏震给出了自己的答案:隐居农村,建造一个属于自己的农场. 让我们来看看他的履历: 2003年毕业于中国科技大学的计算机专业,进入华为: 从华为离职后加入腾讯,当时 ...

  8. oracle move 换用户,Oracle move方法释放delete后的表空间

    在新增记录时,高水位线会慢慢往上移,但是在删除记录后,高水位线却不会往下移. 在使用delete from命令删除大量数据时会导致因HWM引起的性能问题. 删除高水位的最直接的方法是truncate ...

  9. oracle导数据不释放内存,关于ORACLE数据库delete后释放空间问题

    前些天给一家客户开发个接口,还原了正式数据库,由于数据库存储量太大,还原后基本没什么空间了,有个业务表使用频繁,决定删除前期数据,只留近两个月数据以便测试. 数据量太大,等待时间长,就分段删除的,删了 ...

最新文章

  1. 第十六 django进一步了解
  2. 实现windows的负载均衡
  3. 打docker镜像_使用docker构建自己的镜像
  4. codova添加android慢_Android amp; iOS,请自动开始你们的 battle
  5. phpstrom 本地编辑玩文件 自动临时映射到远程服务器
  6. 带你熟悉鸿蒙轻内核Kconfig使用指南
  7. 【mac】Snagit截图时候鼠标变大太大的解决方法
  8. clipboardjs 基本使用方式之一
  9. DataGrid 首次进入页面时,不要加载任何数据
  10. 全面规范的软件需求可以规避项目风险
  11. 新华三模拟器IRF配置
  12. 电脑分辨率设置工具_打印不求人:我猜你并不会设置“分辨率”!
  13. 把Caffe的模型转换为Pytorch模型
  14. VS2013 产品密钥 – 所有版本-亲试,好使!!
  15. linux系统管理考试试题及答案,《Linux系统管理》期末综合试题答案1
  16. C语言”%p”的意思-----printf(%p,p)
  17. 拦截电话--- 关于利用反射 调用系统 hiden的 方法
  18. dellr420部署os_dell r720服务器OS部署
  19. 王者荣耀怎么删除在服务器上建立的账号,王者荣耀账号怎么注销 王者荣耀账号注销方法...
  20. 昨日一宿春雨下,我想永远是清明

热门文章

  1. 很久没写东西了,留个言。
  2. paho.mqtt.embedded-c-master c语言版本架构
  3. stm32 bootloader跳转
  4. java新建测试程序_java – 如何创建一个CloseableHttpResponse对象来帮助测试?
  5. import导入工程时出现error:Description Resource Path Location Type Target runtime com.genuitec.runtime.gener
  6. C++ Primer 5th笔记(chap 16 模板和泛型编程)模板实参推断
  7. (chap2 TCP/IP基础知识) TCP/IP分层模型的通信流程
  8. 区块链BaaS云服务(3)甲骨文 Oracle Blockchain Platform
  9. 《研磨设计模式》chap7 抽象工厂 Abstract Factory
  10. 正则表达式,解决要么有要有没有,但必须开头