delete后加 limit是个好习惯么?( 二 )


  • 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 是个值得养成的好习惯 。
    delete后加 limit是个好习惯么?文章插图
    之前 , 给大家发过三份Java面试宝典 , 这次新增了一份 , 目前总共是四份面试宝典 , 相信在跳槽前一个月按照面试宝典准备准备 , 基本没大问题 。