再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化
繼上篇文章《絕對干貨,教你4分鐘插入1000萬條數(shù)據(jù)到mysql數(shù)據(jù)庫表,快快進來》發(fā)布后在博客園首頁展示得到了挺多的閱讀量,我這篇文章就是對上篇文章的千萬級數(shù)據(jù)庫表在高并發(fā)訪問下如何進行測試訪問
這篇文章的知識點如下:
1.如何自寫幾十行代碼就能模擬測試高并發(fā)下訪問千萬級數(shù)據(jù)庫表
2.比較高并發(fā)下(200次/秒,2000次/秒,10000次/秒)數(shù)據(jù)庫的性能
3.比較千萬級數(shù)據(jù)庫在查詢時加索引與不加索引的巨大差異(說實話,這個測試結(jié)果讓我自己本人也很驚訝)
針對上篇文章插入的1000萬條數(shù)據(jù)到數(shù)據(jù)庫后,我們進行了高并發(fā)下測試(模擬教師輸入姓名和密碼在1秒內(nèi)登錄數(shù)據(jù)庫),線程類代碼如下
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) {//構(gòu)造函數(shù)傳入要查詢登錄的老師姓名和密碼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);//關(guān)閉自動提交,不然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);//獲取結(jié)果集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()+" 查詢結(jié)果:"+id+" 開始時間:"+startTime+" 結(jié)束時間:"+end+" 用時:"+(end-startTime)+"ms");} else {System.out.println(currentThread().getName()+"數(shù)據(jù)庫連接失敗:");}}}?測試類代碼如下:
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();}?一.在沒有加索引的情況下測試:
把數(shù)據(jù)庫的最大連接數(shù)設(shè)置為250:
測試代碼:
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();}}}?測試結(jié)果:
100多秒啊。。。我的天,這用戶體驗也沒準(zhǔn)了O(∩_∩)O哈哈~
二.加索引后再次進行高并發(fā)下測試:
數(shù)據(jù)庫加索引SQL語句如下:這里我有一個疑問,上個星期我加索引等了半個小時我都沒加完索引我就停止了,今天下午居然只用了551秒就加完了索引。。。搞不懂
clean下項目代碼后再次運行(盡量經(jīng)常clean下項目去掉緩存,不然結(jié)果會有出入):
看到這個結(jié)果有沒有被驚呆啊?哈哈加了索引由100多秒提升到1~2毫秒,查詢速度提示1萬多倍,查詢性能得到大幅度變態(tài)級提升~~~
沒加索引之前我查詢單個記錄都要2秒多
用explain查看語句可以知道要掃描全表,性能當(dāng)然大幅度下降
?
?
?
?
?
下面我們來挑戰(zhàn)2000線程同時并發(fā)訪問查詢數(shù)據(jù)庫。看看結(jié)果:
把數(shù)據(jù)庫最大連接數(shù)設(shè)置為2500
測試代碼改為2000
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();}}}?結(jié)果截圖:
性能沒問題,平均幾十毫秒,很滿意
下面我們來挑戰(zhàn)一下1萬個線程同時高并發(fā)訪問,大家可以先想想結(jié)果會怎么樣,哈哈
設(shè)置數(shù)據(jù)庫最大連接數(shù)12000
測試代碼改為10000(再次提示。clean一下項目去掉緩存,這樣結(jié)果更準(zhǔn)確)
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();}}}?結(jié)果如下(運行后發(fā)現(xiàn)電腦有點卡):
結(jié)果出現(xiàn)兩種報錯,1.連接請求被拒絕 2.連接失效 3.不過也有一部分成功連接上并且正確運行
然后我在數(shù)據(jù)庫查看最大連接響應(yīng)數(shù):
可以看出來就算你的數(shù)據(jù)庫設(shè)置為再高你的數(shù)據(jù)庫服務(wù)器也響應(yīng)不過來。。。。頂多響應(yīng)5758個
?小小總結(jié),1.可以自己測試高并發(fā)下挑戰(zhàn)數(shù)據(jù)庫性能,2. 對索引在查詢性能上的強大有一個大概認識? 很適合初學(xué)者學(xué)習(xí)了解
總結(jié)
以上是生活随笔為你收集整理的再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 和csm_CSM媒介研究首发短视频用户价
- 下一篇: 微博polg什么意思_成都网站代运营是什