xiaogaotongxue__ 2022-09-19 10:05 采纳率: 73.3%
浏览 20
已结题

PreparedStatement的性能问题

我测试了一下PreparedStatement(默认不开启预编译,我这里开启了预编译)和Statement的性能,通过向数据库中插入10000条数据来测试,每次的参数都不相同。结果是PreparedStatement的效率比Statement的效率要低。
不是说PreparedStatement是提高了效率吗?它预编译提供了一个模板,应该会提高效率,但是我测试得到的结果却相反
当我开启PreparedStatement的缓存时,它的效率会比PreparedStatement不开启缓存会更高一些。但也只是勉强和Statement相差不多。
我这里有两个疑问:
1.PreparedStatement默认是不开启预编译的?是因为只开启预编译的话,效率会更低吗?还是说一般不会发送大量的sql语句,用不到预编译,所以默认不开启,PreparedStatement一般只是起到了防止SQL攻击的作用
2.PreparedStatement的缓存是为了让一个PreparedStatement对象能用到其他PreparedStatement对象预编译后得到的函数key,从而不需要二次编译,以此提高效率。
但是我测试的时候,并没有用到两个PreparedStatement对象呀,应该不会有性能的提升吧。

还是说我测试的代码不正确吗,求各位解答,在此谢过

public class ceshi {
    public static void main(String[] args) throws Exception{
        PreparedStatementTest();
//        StatementTest();
    }
    public static void PreparedStatementTest() throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        //&useServerPrepStmts=true&cachePrepStmts=true 开启预编译和缓存
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/ceshi?useUnicode=true&characterEncoding=utf8&useSSL=false&useServerPrepStmts=true","root","root");
        String sql = "INSERT into subjecttype VALUES(1,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        long l = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            preparedStatement.setObject(1,1);
            int i1 = preparedStatement.executeUpdate();
        }
        long l1 = System.currentTimeMillis();
        long l2 = l1 - l;
        System.out.println("预编译需要花费的时间"+l2);
        if (preparedStatement!=null) preparedStatement.close();

        if (connection!=null) connection.close();
    }

    public static void StatementTest() throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        //&useServerPrepStmts=true&cachePrepStmts=true 开启预编译和缓存
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/ceshi?useUnicode=true&characterEncoding=utf8&useSSL=false&cachePrepStmts=true ","root","root");
        String sql = "INSERT into subjecttype VALUES(1,";
        Statement Statement = connection.createStatement();
        long l = System.currentTimeMillis();
        for (int i = 1; i < 10000; i++) {
            String sql2 = sql+i+")";
            int i2 = Statement.executeUpdate(sql2);
        }
        long l1 = System.currentTimeMillis();
        long l2 = l1 - l;
        System.out.println("没有预编译花费的时间"+l2);

    if (Statement!=null) Statement.close();

    if (connection!=null) connection.close();

    }
}

我测试得到的结果:
当不开启预编译功能时,做5次测试,单位毫秒
平均值:39028

第一次:39957    第二次:40020    第三次:39251    第四次:36505    第五次:39411

开启预编译,但不开启预编译缓存时
平均值:39540

第一次:40277    第二次:39076    第三次:39137    第四次:39271    第五次:39940

这个结果是开启了预编译,也开启了缓存
平均值:39313

第一次:39682    第二次:39553    第三次:39837    第四次:37847    第五次:39646
  • 写回答

3条回答 默认 最新

  • 三千烦恼丝xzh 2022-09-19 13:58
    关注

    你是希望执行的快一些吗,那你应该使用批处理操作缓存参数注入模板来加速

    
    public static void PreparedStatementTest() throws Exception{
            Class.forName("com.mysql.jdbc.Driver");
            //&useServerPrepStmts=true&cachePrepStmts=true 开启预编译和缓存
            Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/ceshi?useUnicode=true&characterEncoding=utf8&useSSL=false&useServerPrepStmts=true","root","root");
            String sql = "INSERT into subjecttype VALUES(1,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            long l = System.currentTimeMillis();
            for (int i = 0; i < 10000; i++) {
                preparedStatement.setObject(1,1);
                int i1 = preparedStatement.addBatch();
            }
            preparedStatement.executeBatch(); 
            long l1 = System.currentTimeMillis();
            long l2 = l1 - l;
            System.out.println("预编译需要花费的时间"+l2);
            if (preparedStatement!=null) preparedStatement.close();
     
            if (connection!=null) connection.close();
        }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 9月27日
  • 已采纳回答 9月19日
  • 修改了问题 9月19日
  • 创建了问题 9月19日

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么