• MySQL十秒插入百万条数据


    mysql数据库准备

    1. private String Driver = "com.mysql.cj.jdbc.Driver";
    2. private String url ="jdbc:mysql://localhost:3306/mp?serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";
    3. private String user = "root";
    4. private String password = "root";
    5. Connection connection = null;
    6. PreparedStatement ps = null;
    7. ResultSet rs = null;
    8. //封装与数据库建立连接的类
    9. public void coon() throws Exception{
    10. Class.forName(Driver);
    11. connection = DriverManager.getConnection(url,user,password);
    12. }
    13. //封装异常类
    14. public void erro(){
    15. try {
    16. if (rs!=null){
    17. rs.close();
    18. }
    19. if (ps!=null){
    20. ps.close();
    21. }
    22. if (connection!=null){
    23. connection.close();
    24. }
    25. } catch (Exception e) {
    26. e.printStackTrace();
    27. }
    28. }

    方式一:普通插入

    1. package com.wt;
    2. import org.junit.Test;
    3. import java.sql.Connection;
    4. import java.sql.DriverManager;
    5. import java.sql.PreparedStatement;
    6. import java.sql.ResultSet;
    7. /**
    8. * @Author wt
    9. * @Date 2022/11/14 21:17
    10. * @PackageName:com.wt
    11. * @ClassName: TestAddBatch01
    12. * @Description: TODO
    13. * @Version 1.0
    14. */
    15. public class TestAddBatch01 {
    16. private String Driver = "com.mysql.cj.jdbc.Driver";
    17. private String url ="jdbc:mysql://localhost:3306/mp?serverTimezone=Asia/Shanghai";
    18. private String user = "root";
    19. private String password = "root";
    20. Connection connection = null;
    21. PreparedStatement ps = null;
    22. ResultSet rs = null;
    23. public void coon() throws Exception{
    24. Class.forName(Driver);
    25. connection = DriverManager.getConnection(url,user,password);
    26. }
    27. public void erro(){
    28. try {
    29. if (rs!=null){
    30. rs.close();
    31. }
    32. if (ps!=null){
    33. ps.close();
    34. }
    35. if (connection!=null){
    36. connection.close();
    37. }
    38. } catch (Exception e) {
    39. e.printStackTrace();
    40. }
    41. }
    42. @Test
    43. public void ccc(){
    44. long start = System.currentTimeMillis();
    45. String sql = "insert into a(id, name) VALUES (?,null)";
    46. try {
    47. coon();
    48. ps = connection.prepareStatement(sql);
    49. for (int i = 1; i <= 1000000; i++) {
    50. ps.setObject(1, i);//填充sql语句种得占位符
    51. ps.execute();//执行sql语句
    52. }
    53. } catch (Exception e) {
    54. e.printStackTrace();
    55. } finally {
    56. erro();
    57. }
    58. System.out.println("百万条数据插入用时:" + (System.currentTimeMillis() - start)+"【单位:毫秒】");
    59. }
    60. }

    用时:62分钟多 

    方式二:使用批处理插入

    1. package com.wt;
    2. import org.junit.Test;
    3. import java.sql.Connection;
    4. import java.sql.DriverManager;
    5. import java.sql.PreparedStatement;
    6. import java.sql.ResultSet;
    7. /**
    8. * @Author wt
    9. * @Date 2022/11/14 20:25
    10. * @PackageName:com.wt.util
    11. * @ClassName: TestAddBatch
    12. * @Description: TODO
    13. * @Version 1.0
    14. */
    15. public class TestAddBatch {
    16. private String Driver = "com.mysql.cj.jdbc.Driver";
    17. private String url ="jdbc:mysql://localhost:3306/mp?serverTimezone=Asia/Shanghai";
    18. private String user = "root";
    19. private String password = "root";
    20. Connection connection = null;
    21. PreparedStatement ps = null;
    22. ResultSet rs = null;
    23. public void coon() throws Exception{
    24. Class.forName(Driver);
    25. connection = DriverManager.getConnection(url,user,password);
    26. }
    27. public void erro(){
    28. try {
    29. if (rs!=null){
    30. rs.close();
    31. }
    32. if (ps!=null){
    33. ps.close();
    34. }
    35. if (connection!=null){
    36. connection.close();
    37. }
    38. } catch (Exception e) {
    39. e.printStackTrace();
    40. }
    41. }
    42. @Test
    43. public void ccc(){
    44. long start = System.currentTimeMillis();
    45. String sql = "insert into a(id, name) VALUES (?,null)";
    46. try {
    47. coon();
    48. ps = connection.prepareStatement(sql);
    49. // connection.setAutoCommit(false);//取消自动提交
    50. for (int i = 1; i <= 1000000; i++) {
    51. ps.setObject(1, i);
    52. ps.addBatch();
    53. if (i % 1000 == 0) {
    54. ps.executeBatch();
    55. ps.clearBatch();
    56. }
    57. }
    58. ps.executeBatch();
    59. ps.clearBatch();
    60. // connection.commit();//所有语句都执行完毕后才手动提交sql语句
    61. } catch (Exception e) {
    62. e.printStackTrace();
    63. } finally {
    64. erro();
    65. }
    66. System.out.println("百万条数据插入用时:" + (System.currentTimeMillis() - start)+"【单位:毫秒】");
    67. }
    68. }

     方式一、二总结:到此可以看出其实其处理程序及批处理是没有起作用的,为此我们使用方式三

    方式三:通过连接配置url设置【&rewriteBatchedStatements=true】(设置重写批处理语句)

    url地址后注意添加【&rewriteBatchedStatements=true】

    private String url ="jdbc:mysql://localhost:3306/mp?serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";
    

    方法三较于方法二的改变是只是url地址上的改变,其它没有任何修改 

    1. package com.wt;
    2. import org.junit.Test;
    3. import java.sql.Connection;
    4. import java.sql.DriverManager;
    5. import java.sql.PreparedStatement;
    6. import java.sql.ResultSet;
    7. /**
    8. * @Author wt
    9. * @Date 2022/11/14 20:25
    10. * @PackageName:com.wt.util
    11. * @ClassName: TestAddBatch
    12. * @Description: TODO
    13. * @Version 1.0
    14. */
    15. public class TestAddBatch {
    16. private String Driver = "com.mysql.cj.jdbc.Driver";
    17. private String url ="jdbc:mysql://localhost:3306/mp?serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";
    18. private String user = "root";
    19. private String password = "root";
    20. Connection connection = null;
    21. PreparedStatement ps = null;
    22. ResultSet rs = null;
    23. public void coon() throws Exception{
    24. Class.forName(Driver);
    25. connection = DriverManager.getConnection(url,user,password);
    26. }
    27. public void erro(){
    28. try {
    29. if (rs!=null){
    30. rs.close();
    31. }
    32. if (ps!=null){
    33. ps.close();
    34. }
    35. if (connection!=null){
    36. connection.close();
    37. }
    38. } catch (Exception e) {
    39. e.printStackTrace();
    40. }
    41. }
    42. @Test
    43. public void ccc(){
    44. long start = System.currentTimeMillis();
    45. String sql = "insert into a(id, name) VALUES (?,null)";
    46. try {
    47. coon();
    48. ps = connection.prepareStatement(sql);
    49. for (int i = 1; i <= 1000000; i++) {
    50. ps.setObject(1, i);
    51. ps.addBatch();
    52. if (i % 1000 == 0) {
    53. ps.executeBatch();
    54. ps.clearBatch();
    55. }
    56. }
    57. ps.executeBatch();
    58. ps.clearBatch();
    59. } catch (Exception e) {
    60. e.printStackTrace();
    61. } finally {
    62. erro();
    63. }
    64. System.out.println("百万条数据插入用时:" + (System.currentTimeMillis() - start)+"【单位:毫秒】");
    65. }
    66. }

    用时:【10秒左右】

     

     

     

    到此批处理语句才正是生效

    注意

    数据库连接的url设置了【&rewriteBatchedStatements=true】时,java代码种的sql语句不能有分号【;】号,否则批处理语句打包就会出现错误,导致后面的sql语句提交出现【BatchUpdateException】异常

    方式四:通过数据库连接取消自动提交,手动提交数据

    1. package com.wt;
    2. import org.junit.Test;
    3. import java.sql.Connection;
    4. import java.sql.DriverManager;
    5. import java.sql.PreparedStatement;
    6. import java.sql.ResultSet;
    7. /**
    8. * @Author wt
    9. * @Date 2022/11/14 20:25
    10. * @PackageName:com.wt.util
    11. * @ClassName: TestAddBatch
    12. * @Description: TODO
    13. * @Version 1.0
    14. */
    15. public class TestAddBatch {
    16. private String Driver = "com.mysql.cj.jdbc.Driver";
    17. private String url ="jdbc:mysql://localhost:3306/mp?serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true";
    18. private String user = "root";
    19. private String password = "root";
    20. Connection connection = null;
    21. PreparedStatement ps = null;
    22. ResultSet rs = null;
    23. public void coon() throws Exception{
    24. Class.forName(Driver);
    25. connection = DriverManager.getConnection(url,user,password);
    26. }
    27. public void erro(){
    28. try {
    29. if (rs!=null){
    30. rs.close();
    31. }
    32. if (ps!=null){
    33. ps.close();
    34. }
    35. if (connection!=null){
    36. connection.close();
    37. }
    38. } catch (Exception e) {
    39. e.printStackTrace();
    40. }
    41. }
    42. @Test
    43. public void ccc(){
    44. long start = System.currentTimeMillis();
    45. String sql = "insert into a(id, name) VALUES (?,null)";
    46. try {
    47. coon();
    48. ps = connection.prepareStatement(sql);
    49. connection.setAutoCommit(false);//取消自动提交
    50. for (int i = 1; i <= 1000000; i++) {
    51. ps.setObject(1, i);
    52. ps.addBatch();
    53. if (i % 1000 == 0) {
    54. ps.executeBatch();
    55. ps.clearBatch();
    56. }
    57. }
    58. ps.executeBatch();
    59. ps.clearBatch();
    60. connection.commit();//所有语句都执行完毕后才手动提交sql语句
    61. } catch (Exception e) {
    62. e.printStackTrace();
    63. } finally {
    64. erro();
    65. }
    66. System.out.println("百万条数据插入用时:" + (System.currentTimeMillis() - start)+"【单位:毫秒】");
    67. }
    68. }

     用时:【9秒左右】

    总结:

    1.使用批量提交数据,url一定要设置允许重写批量提交【rewriteBatchedStatements=true】,以及此时的sql语句一定不能有分号,否则有【BatchUpdateException】异常,

    2.其他的就正常使用PreparedStatement ps;的以下三个方法即可
         *      ps.addBatch();      将sql语句打包到一个容器中
         *      ps.executeBatch();  将容器中的sql语句提交
         *      ps.clearBatch();    清空容器,为下一次打包做准备

     

  • 相关阅读:
    maven 本地jar打包到镜像仓库
    南美巴西市场最全分析开发攻略,收藏一篇就够了
    QT中怎么设置定时器/周期任务/定时触发任务
    实战
    C++标准输入输出及命名空间
    fastboot 找不到设备
    03-JAVA设计模式-策略模式
    天月德统计
    HALCON联合C#机械手视觉定位——初始化
    JavaScript变量存储机制
  • 原文地址:https://blog.csdn.net/weixin_56028042/article/details/127855696