小言_互联网的博客

MySQL十秒插入百万条数据

294人阅读  评论(0)

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();    清空容器,为下一次打包做准备

 


转载:https://blog.csdn.net/weixin_56028042/article/details/127855696
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场