测试2000线程并发下同时查询1000万条数据库表及索引优化

继上篇文章《绝对干货,教你4分钟插入1000万条数据到mysql数据库表,快快进来》发布后在博客园首页展示得到了挺多的阅读量,我这篇文章就是对上篇文章的千万级数据库表在高并发访问下如何进行测试访问

这篇文章的知识点如下:

1.如何自写几十行代码就能模拟测试高并发下访问千万级数据库表

2.比较高并发下(200次/秒,2000次/秒,10000次/秒)数据库的性能

3.比较千万级数据库在查询时加索引与不加索引的巨大差异(说实话,这个测试结果让我自己本人也很惊讶)

针对上篇文章插入的1000万条数据到数据库后,我们进行了高并发下测试(模拟教师输入姓名和密码在1秒内登录数据库),线程类代码如下

package  insert;
 
import  java.sql.Connection;
import  java.sql.DriverManager;
import  java.sql.ResultSet;
import  java.sql.SQLException;
import  java.sql.Statement;
 
public  class  ThreadToMysql  extends  Thread {
     public  String teacherName;
     public  String password;
     public  ThreadToMysql(String teacherName, String password) { //构造函数传入要查询登录的老师姓名和密码
         
         this .teacherName=teacherName;
         this .password=password;
     }
     
     public  void  run() {
          String url =  "jdbc:mysql://127.0.0.1/teacher"
          String name =  "com.mysql.jdbc.Driver"
          String user =  "root"
          String password =  "123456"
         Connection conn =  null
         try  {
             Class.forName(name);
             conn = DriverManager.getConnection(url, user, password); //获取连接 
             conn.setAutoCommit( false ); //关闭自动提交,不然conn.commit()运行到这句会报错
         catch  (ClassNotFoundException e1) {
             e1.printStackTrace();
         catch  (SQLException e) {
             e.printStackTrace();
         }
         if  (conn!= null ) {
             Long startTime=System.currentTimeMillis(); //开始时间
             String sql= "select id from t_teacher where t_name='" +teacherName+ "' and t_password='" +password+ "'" ; //SQL语句
             String id= null ;
             try  {
                 Statement stmt=conn.createStatement();
                 ResultSet rs=stmt.executeQuery(sql); //获取结果集
                 if  (rs.next()) {
                     id=rs.getString( "id" );
                 }
                 conn.commit();
                 stmt.close();
                 conn.close();
             catch  (SQLException e) {
                 e.printStackTrace();
             }
                 Long end=System.currentTimeMillis();
                 System.out.println(currentThread().getName()+ "  查询结果:" +id+ "   开始时间:" +startTime+ "  结束时间:" +end+ "  用时:" +(end-startTime)+ "ms" );
             
             
         else  {
             System.out.println(currentThread().getName()+ "数据库连接失败:" );
         }
     }
     
}


测试类代码如下:

1
2
3
4
5
6
7
8
9
10
11
package  insert;
 
public  class  TestThreadToMysql {
 
     public  static  void  main(String[] args) {
         for  ( int  i =  1 ; i <= 2000 ; i++) {
             String teacherName=String.valueOf(i);
             new  ThreadToMysql(teacherName,  "123456" ).start();
     
 
}

 一.在没有加索引的情况下测试:

把数据库的最大连接数设置为250:

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
package  insert;
 
public  class  TestThreadToMysql {
 
     public  static  void  main(String[] args) {
         for  ( int  i =  1 ; i <= 200 ; i++) {
             String teacherName=String.valueOf(i);
             new  ThreadToMysql(teacherName,  "123456" ).start();
         }
     }
 
}

 测试结果:

100多秒啊。。。我的天,这用户体验也没准了O(∩_∩)O哈哈~

二.加索引后再次进行高并发下测试:

数据库加索引SQL语句如下:这里我有一个疑问,上个星期我加索引等了半个小时我都没加完索引我就停止了,今天下午居然只用了551秒就加完了索引。。。搞不懂

clean下项目代码后再次运行(尽量经常clean下项目去掉缓存,不然结果会有出入):

看到这个结果有没有被惊呆啊?哈哈加了索引由100多秒提升到1~2毫秒,查询速度提示1万多倍,查询性能得到大幅度变态级提升~~~

没加索引之前我查询单个记录都要2秒多

用explain查看语句可以知道要扫描全表,性能当然大幅度下降

 

 

 

 

 

下面我们来挑战2000线程同时并发访问查询数据库。看看结果:

把数据库最大连接数设置为2500

测试代码改为2000

1
2
3
4
5
6
7
8
9
10
11
12
package  insert;
 
public  class  TestThreadToMysql {
 
     public  static  void  main(String[] args) {
         for  ( int  i =  1 ; i <= 2000 ; i++) {
             String teacherName=String.valueOf(i);
             new  ThreadToMysql(teacherName,  "123456" ).start();
         }
     }
 
}

 结果截图:

性能没问题,平均几十毫秒,很满意

下面我们来挑战一下1万个线程同时高并发访问,大家可以先想想结果会怎么样,哈哈

设置数据库最大连接数12000

测试代码改为10000(再次提示。clean一下项目去掉缓存,这样结果更准确)

1
2
3
4
5
6
7
8
9
10
11
12
package  insert;
 
public  class  TestThreadToMysql {
 
     public  static  void  main(String[] args) {
         for  ( int  i =  1 ; i <= 10000 ; i++) {
             String teacherName=String.valueOf(i);
             new  ThreadToMysql(teacherName,  "123456" ).start();
         }
     }
 
}


结果如下(运行后发现电脑有点卡):

结果出现两种报错,1.连接请求被拒绝 2.连接失效 3.不过也有一部分成功连接上并且正确运行

然后我在数据库查看最大连接响应数:

可以看出来就算你的数据库设置为再高你的数据库服务器也响应不过来。。。。顶多响应5758个

 小小总结,1.可以自己测试高并发下挑战数据库性能,2. 对索引在查询性能上的强大有一个大概认识  很适合初学者学习了解

转载https://www.cnblogs.com/fanwencong/p/5774117.html

之前就是根据这段文章实现的多线程在实际项目中查询数据库的优化操作,对个人日志表进行查询优化,传入用户id跟查询时间以及判断条件,根据线程池去做数据库表快速查询,现在做一个文章整理回顾。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值