• SQLite利用事务实现批量插入(提升效率)


    在尝试过SQLite批量插入一百万条记录,执行时长高达20多分钟后,就在想一个问题,这样的性能是不可能被广泛应用的,更不可能出现在真实的生产环境中,那么对此应该如何优化一下呢?

    首先分析一下批量插入的逻辑

    //循环插入1,000,000条记录
    for (int i = 0; i < 1000000; i++) {
        //执行插入操作
        rowsInserted = pstmt.executeUpdate();
    }
    //输出计时
    

    上述代码创建一个循环,循环一百万次,每一次循环更新插入一条数据,这样一来就是对数据库操作了一百万次,虽然实现了批量操作,但是却对数据库造成了很大的开销,如果数据量再进一步扩大,此方法保不齐会让服务崩掉,所以这不是个最优解。

    能不能对数据库只操作一次,就能实现数据的批量操作呢?

    事务

    我可以开启一个事务,把一百万次的循环插入放到一个批处理中,最后提交事务,这样一来只对数据库进行一次操作实现数据批量插入。

    接下来设计代码:

    import java.sql.*;
    
    public class SQLiteBatchInsert {
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement pstmt = null;
            try {
                //建立数据库连接
                Class.forName("org.sqlite.JDBC");
                conn = DriverManager.getConnection("jdbc:sqlite:D:\\env\\SQLite\\data\\user.db");
                //设置手动提交事务
                conn.setAutoCommit(false);
                String tableName = "user";
                // 准备SQL语句
                String sql = "INSERT INTO " + tableName + " (name, age) VALUES (?,?)";
                pstmt = conn.prepareStatement(sql);
                //批量添加数据
                for (int i = 0; i < 1000000; i++) {
                    pstmt.setString(1, "王五");
                    pstmt.setString(2, "25");
                    pstmt.addBatch();
                }
                // 记录执行开始时间
                double startTime = System.currentTimeMillis();
                //执行批处理
                pstmt.executeBatch();
                //提交事务
                conn.commit();
                //记录执行结束时间
                double endTime = System.currentTimeMillis();
                double duration = endTime - startTime;
                System.out.println("Batch insert successful!");
                System.out.println("执行时间为:"+duration/1000+"s");
            } catch (SQLException | ClassNotFoundException e) {
                e.printStackTrace();
                if (conn != null) {
                    try {
                        //如果出现异常,回滚事务
                        conn.rollback();
                    } catch (SQLException ex) {
                        ex.printStackTrace();
                    }
                }
            } finally {
                //关闭资源
                try {
                    if (pstmt != null) pstmt.close();
                    if (conn != null) conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    运行后发现,执行时间惊人的只有 1s 左右

    请添加图片描述

    为了验证这一结果,我不得不去数据库里查一下,果不其然插入成功

    请添加图片描述

    看来,SQLite 利用事务执行批量操作完全是个可行的方案,大大的降低了对数据库的开销,极大的减少了执行时间,效率有了质的提升。


  • 相关阅读:
    DBCO-PEG-Comarin|二苯并环辛炔-聚乙二醇-香豆素|DBCO-PEG-香豆素
    C语言枚举和联合体
    一种多媒体框架中的零buffer拷贝实现机制
    如何利用k-means算法对图片颜色进行聚类并实现图像压缩?(附Python代码+数据集)
    [附源码]java毕业设计壹家吃货店网站
    java配置GDAL
    C++学习笔记12 - 构造函数和析构函数
    浅析RSA非对称加密算法
    YOLO目标检测——钢表面缺陷检测数据集下载分享【含对应voc、coco和yolo三种格式标签】
    非暴力沟通!
  • 原文地址:https://blog.csdn.net/ITMuscle/article/details/138761174