繼上篇文章《絕對乾貨,教你4分鐘插入1000萬條數據到mysql數據庫表,快快進來》發佈後在博客園首頁展現獲得了挺多的閱讀量,我這篇文章就是對上篇文章的千萬級數據庫表在高併發訪問下如何進行測試訪問html
這篇文章的知識點以下:java
1.如何自寫幾十行代碼就能模擬測試高併發下訪問千萬級數據庫表mysql
2.比較高併發下(200次/秒,2000次/秒,10000次/秒)數據庫的性能sql
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()+"數據庫鏈接失敗:"); } } }
測試類代碼以下:服務器
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:函數
測試代碼:高併發
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
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一下項目去掉緩存,這樣結果更準確)
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. 對索引在查詢性能上的強大有一個大概認識 很適合初學者學習瞭解