zoukankan      html  css  js  c++  java
  • JDBC的批量更新测试

    上回书说道MySQL的auto-reconnect的问题,可以通过重新建立Connection的方法解决之,于是我就更新了一下该数据库封装 类。这里介绍一下背景:为了使用方便,一些小型项目中,我倾向于直接使用JDBC,这样执行效率和开发效率相对而言都比较高,而实际使用中,所有的数据库 操作,都被封装在一个DatabaseFactory类中(有时间我会考虑一下,整理一下Open Source It)。

    在修改这个类的过程中,顺便研究了下数据批量更新的效率问题,分析结果如下。由于对于不同的数据库,效果也不尽相同,这里以MySQL和Oracle为例,并分开描述:

    MySQL:

    MySQL本身并不支持批量更新,只是驱动程序提供了这个特性,只有高版本才支持该特性,并且连接URL上必须加上

    1
    rewriteBatchedStatements=true

    这样的参数,这样驱动程序会自动将多条SQL语句拼接成一条,从而提高了执行效率。

    1
    2
    3
    4
    5
    6
    7
    ...
    for (int i = 0; i < sqlList.size(); i++) {
    stmt.addBatch(sqlList.get(i));
    }
     
    stmt.executeBatch();
    connection.commit();

    效率提升是必然的,原因很简单:非批量更新方式,autoCommit=true,每一条SQL语句都会自动提交,都会产生网络数据包、磁盘IO。 而批量更新方式,只会产生少量的数据包,因为很多条SQL语句被打成一个数据包,一次性的通过网络传输到服务器,相应的,服务器的IO操作也少了很多,当 然效率自然会提高。

    就是因为这个和网路相关,所以网络环境不同,产生的提升效果也不相同,经测试,在比较快速的网络环境下,比如局域网,我的试验结果是:10万条SQL语句,在非批量情况下,使用了约36秒,而批量操作只使用了约9秒,效率提高了3倍。

    如果在比较差的网络环境下,提升的效果会更明显,我使用VPN从家里连接到公司的内网,更新1万条数据,非批量 方式,大概需要270秒左右,而批量方式大约9秒,提升了近30倍。效率提升的倍数和很多因素相关,比如刚才提到的网络环境,每次提交多少条SQL语句也 很关键,并且MySQL表的类型也会影响这个:MyISAM类型的表的提升效率就远远的高于InnoDB类型的表。

    注:上述的所有的所有测试都没有使用Prepared Statement,只是使用普通的Statement和executeBatch(),如果使用Prepared Statement,几乎没有任何效率提升,后来发现是因为我用的mysql-connector-java的版本过低(5.1.8),替换为 5.1.17后,VPN状态,效率提升50倍左右。

    Oracle:

    和MySQL相反,Oracle使用批量更新,如果不使用Prepared Statement,效果可能会更差,使用了Prepared Statement,我用VPN连接到公司的内网,效率提高了75倍左右。可能是因为我用的Oracle JDBC驱动对非Prepared Statement的支持不够好吧。

    MSSQL:

    待测试,稍后更新…

    小结

    数据库更新的效率提升,由很多原因决定:网络环境,服务器内存、服务器I/O、驱动版本、代码编写方式、数据库的版本、表的类型等。我们必须综合考量所有因素,才能达到理想的效果。推荐你在你实际的环境中做相应的测试,找出最优的方法,别人的优化方法,不一定完全适用于你,比如这里提到的提升倍数,每个人的试验结果肯定不一样。

  • 相关阅读:
    链串
    一个外行谈行业应用的营销问题
    SharePoint 2013的100个新功能之场管理
    Deep Learning and Shallow Learning
    [IOS]UIWebView 请求网络页面或者加载本地资源页面
    九度OJ 打印日期 (模拟)
    STM32学习之路-SysTick的应用(时间延迟)
    box-shadow
    让算法会说话之高速排序
    A5-1和DES两个加密算法的学习
  • 原文地址:https://www.cnblogs.com/shihao/p/2555489.html
Copyright © 2011-2022 走看看