Java面试题汇总---操作delete或者update语句,为什么要加个limit或者循环分批次

面试题分享原因
面试官:平时写sql的时候,操作delete或者update语句,你会使用limit吗?
我:会使用
面试官:为什么要加个limit
我:防止误删除的操作导致删库,造成数据大量丢失,使用了limit后可以定量删除,数据量少的情况下可以使用binlog进行恢复删除的数据
面试官:除了这个方法还有其他实现方式吗?
我:。。。。
面试官:还可以使用循环批次的方式,你可以了解一下
我:多谢面试官,我学习了

操作delete或者update语句,为什么要加个limit或者循环分批次

  1. 避免锁表或阻塞操作:
  • 对于大量数据的删除或更新操作,一次性执行可能会导致数据库长时间持有锁(如行锁、表锁或间隙锁),尤其是在高并发环境下,这可能会阻塞其他对同一表的读写操作,降低数据库整体性能和可用性。通过分批次删除或更新,每次只处理一部分数据,可以减少锁的持有时间,降低对其他事务的影响。
  1. 控制事务大小,减少回滚成本:
  • 大批量操作通常会在一个事务中完成,如果事务过大,一旦在执行过程中发生异常需要回滚,数据库需要撤销的操作也会非常多,这会消耗大量的系统资源并可能导致长时间的阻塞。分批处理可以将事务规模控制在较小范围内,降低回滚成本,提高系统的稳定性和响应速度。
  1. 避免超出内存限制:
  • 对于大规模的数据操作,数据库服务器可能需要将大量数据加载到内存中进行处理。一次性删除或更新大量数据可能导致内存溢出,影响服务器稳定性。通过分批次执行,可以确保每次操作的数据量在服务器内存承受范围内,避免此类问题。
  1. 减少对主从复制和备份的影响:
  • 在采用主从复制的架构中,大规模的删除或更新操作会产生大量的 binlog 事件,可能导致主从延迟增大。分批处理可以减少一次性产生的 binlog量,减轻主从复制压力。此外,对于基于时间点的备份策略,大规模数据变更可能导致备份窗口期间的数据不一致。分批次操作可以减小每个时间点的数据变化量,有助于提高备份的一致性
  1. 防止全表扫动生成大量临时数据:
  • 在没有合适索引支持的情况下,DELETE或UPDATE语句可能导致全表扫描,生成大量临时数据。特别是在没有WHERE条件或条件选择性较差的情况下,一次性操作可能导致严重的性能问题。分批次执行结合有效的索引使用,可以减少每次操作涉及的数据量,降低对系统资源的需求。
  1. 便于监控与控制:
  • 分批次执行可以让操作者更好地监控执行进度,及时发现并处理潜在问题。如果在执行过程中发现问题,可以立即停止后续批次,避免造成更大影响。同时,可以根据实际情况动态调整每次处理的数据量,以适应系统负载的变化。

综上所述,为DELETE或UPDATE语句添加LIMIT子句或采用循环分批次删除/更新,是出于优化数据库性能、保证系统稳定性、降低风险以及便于监控等方面的考虑。在实际操作时,应根据数据量、服务器资源、业务需求等因素,合理设置批次大小和执行间隔,以达到最佳效果。

在Java中使用JDBC操作delete或update语句并分批次执行,可以通过循环来控制每批处理的记录数量
以下是一个示例代码,展示了如何分批删除数据库中的数据:
java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
 
public class BatchUpdateExample {
    private static final String URL = "jdbc:mysql://localhost:3306/your_database";
    private static final String USER = "your_username";
    private static final String PASSWORD = "your_password";
 
    public static void main(String[] args) {
        int batchSize = 1000; // 设置每批次的大小
        int start = 0; // 起始索引
 
        Connection conn = null;
        PreparedStatement pstmt = null;
 
        try {
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
            conn.setAutoCommit(false); // 开启事务
 
            String sql = "DELETE FROM your_table WHERE your_condition LIMIT ?";
            pstmt = conn.prepareStatement(sql);
 
            do {
                pstmt.setInt(1, batchSize);
                pstmt.executeUpdate(); // 执行删除
                conn.commit(); // 提交事务
 
                start += batchSize; // 更新起始索引
            } while (start < totalCount); // totalCount是你要删除的总记录数
 
            conn.commit(); // 如果最后一批数据已经删除完毕,确保提交事务
 
        } catch (SQLException e) {
            try {
                if (conn != null) {
                    conn.rollback(); // 发生异常,回滚事务
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null) pstmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

操作delete或者update语句,加limit或者循环分批次的优缺点

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值