繼上篇文章《絕對干貨,教你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()+"數據庫連接失敗:"); } } }
測試類代碼如下:
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. 對索引在查詢性能上的強大有一個大概認識 很適合初學者學習了解