日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

数据库压力测试

發(fā)布時(shí)間:2024/3/13 数据库 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据库压力测试 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、 存儲過程和觸發(fā)器實(shí)驗(yàn)

  • 請?jiān)谀氵x用的數(shù)據(jù)庫平臺上,針對你的應(yīng)用場景,對如下操作至少各實(shí)現(xiàn)一個存儲過程:
    1)單表或多表查詢 2)數(shù)據(jù)插入 3)數(shù)據(jù)刪除 4)數(shù)據(jù)修改
    1)單表查詢,結(jié)果如下:
  • –查詢u_id大于輸入的num的
    drop procedure if exists sl;
    – 如果存在就drop
    delimiter //
    – 定義為碰到//才表示語句結(jié)束
    create procedure sl(num int)
    begin
    select * from User_tbl where u_id > num;
    end //
    delimiter ;
    – 定義為碰到;表示語句結(jié)束
    call sl(5);
    多表查詢結(jié)果如下:
    查找u_id為輸入的n的用戶的朋友圈內(nèi)容和他的真實(shí)姓名

    drop procedure if exists lo;
    – 如果存在就drop
    delimiter //
    create procedure lo(n int)
    begin
    select p_content,u_truename from User_tbl,Circlemsg_tbl
    where user_tbl.u_id=n
    and circlemsg_tbl.p_uid=n;
    end //
    delimiter ;
    call lo(6);
    2)數(shù)據(jù)插入
    drop procedure if exists sp1;
    – 如果存在就drop
    delimiter //
    – 定義為碰到//才表示語句結(jié)束
    create procedure sp1(in account varchar(255),in password varchar(255),in name varchar(255),in tname varchar(255),in sex varchar(255))
    begin
    insert into user_tbl(u_account,u_password,u_registtime,u_lock,u_style,u_username,u_truename,u_sex,u_location,u_face,u_intro) values(account,password,now(), 0, ‘a(chǎn)’, name, tname, sex, ‘null’, ‘null’, ‘null’);
    select * from user_tbl;
    end //
    delimiter ;
    call sp1(‘www’,‘32ewew’,‘wan’,‘dongyu’,‘男’);

    3)數(shù)據(jù)刪除,結(jié)果如下:

    – 數(shù)據(jù)刪除
    drop procedure if exists del;
    – 如果存在就drop
    delimiter //
    – 定義為碰到//才表示語句結(jié)束
    create procedure del(id int)
    begin
    delete from Circlemsg_tbl where p_id = id;
    select * from Circlemsg_tbl;
    end //
    delimiter ;
    call del(3);
    – 定義為碰到;表示語句結(jié)束
    call del();
    – 定義為碰到;表示語句結(jié)束
    4)數(shù)據(jù)修改,結(jié)果如下:

    drop procedure if exists up;
    – 如果存在就drop
    delimiter //
    – 定義為碰到//才表示語句結(jié)束
    create procedure up(name varchar(255),psd varchar(255))
    begin
    UPDATE user_tbl SET u_password = psd WHERE u_username = name;
    select * from user_tbl;
    end //
    delimiter ;
    call up(‘wan’,‘11111’);
    – 定義為碰到;表示語句結(jié)束
    2.通過ODBC、OLEDB、JDBC或任意其他的途徑,在前端程序(C/S或B/S模式)中調(diào)用所實(shí)現(xiàn)的后臺存儲過程。
    我使用的是JDBC實(shí)現(xiàn)在前端程序調(diào)用數(shù)據(jù)庫后臺存儲過程,代碼過長,放入壓縮包中。(網(wǎng)頁采用的是Jquery架構(gòu)),網(wǎng)頁整體頁面如下:

  • 數(shù)據(jù)查詢:(輸入用戶名,點(diǎn)擊查詢按鈕即可查詢到數(shù)據(jù)庫中該用戶的信息并在頁面顯示出來),結(jié)果如下圖:

  • 數(shù)據(jù)插入操作 插入用戶信息,點(diǎn)擊頁面的添加按鈕,在動態(tài)彈出的表單中輸入用戶信息,點(diǎn)擊確認(rèn),即可完成添加,添加結(jié)果自動返回顯示,操作界面如下圖:

  • 數(shù)據(jù)刪除操作 點(diǎn)擊每個用戶欄對應(yīng)的最右邊的刪除鏈接,即可實(shí)現(xiàn)對該用戶的刪除操作,刪除完成后自動顯示當(dāng)前數(shù)據(jù)庫的狀態(tài)結(jié)果。如下圖所示:

  • 數(shù)據(jù)修改操作,點(diǎn)擊每個用戶欄對應(yīng)的最右邊的修改密碼鏈接,跳轉(zhuǎn)到修改密碼的頁面,輸入新的密碼,即可實(shí)現(xiàn)對該用戶的密碼修改操作,如下圖所示:

  • 跳轉(zhuǎn):

    3.在你的案例場景中,分別設(shè)計(jì)并實(shí)現(xiàn)一個由數(shù)據(jù)插入、數(shù)據(jù)更新、數(shù)據(jù)刪除所引發(fā)的觸發(fā)器(前觸發(fā)或后觸發(fā)都可以),測試觸發(fā)器執(zhí)行效果。
    –創(chuàng)建記錄微信用戶的表wechat_count,默認(rèn)為0
    CREATE TABLE wechat_count (
    wechat_count INT(11) DEFAULT 0
    );
    INSERT INTO wechat_count VALUES(0);
    select * from wechat_count;

    1) 數(shù)據(jù)插入
    –創(chuàng)建簡單觸發(fā)器,在向wechat_tbl表INSERT數(shù)據(jù)時(shí),wechat_count增加
    CREATE TRIGGER trigger_insert
    AFTER INSERT
    ON user_tbl FOR EACH ROW
    UPDATE wechat_count SET wechat_count=wechat_count+1;

    --驗(yàn)證觸發(fā)器,插入一個同學(xué)信息,wechat_count應(yīng)該增加1個

    call sp1(‘weqqw’,‘3121w’,‘a(chǎn)nan’,‘pengyuyan’,‘男’);;
    select * from wechat_count;
    結(jié)果如下:

    2) 數(shù)據(jù)更新
    –數(shù)據(jù)更新
    –創(chuàng)建簡單觸發(fā)器,在向wechat_tbl表UPDATA數(shù)據(jù)時(shí),
    –創(chuàng)建記錄數(shù)據(jù)更新技術(shù)的updata_count
    CREATE TABLE updata_count (
    updata_count INT(11) DEFAULT 0
    );
    INSERT INTO updata_count VALUES(0);
    select * from updata_count;

    CREATE TRIGGER trigger_updata
    AFTER UPDATE
    ON user_tbl FOR EACH ROW
    UPDATE updata_count SET updata_count=updata_count+1;

    –驗(yàn)證觸發(fā)器
    delimiter ;
    call up(‘2wed’,‘111121311’);
    select * from user_tbl;
    select * from updata_count;

    3) 數(shù)據(jù)刪除
    –數(shù)據(jù)刪除
    –創(chuàng)建簡單觸發(fā)器,在向wechat_tbl表DELETE數(shù)據(jù)時(shí),wechat_count減少
    CREATE TRIGGER trigger_delete
    AFTER DELETE
    ON user_tbl FOR EACH ROW
    UPDATE wechat_count SET wechat_count=wechat_count-1;
    DELETE FROM user_tbl WHERE u_id=11;
    select * from wechat_count;

    二、 壓力測試與索引實(shí)驗(yàn)(注意提前備份好機(jī)器上的關(guān)鍵數(shù)據(jù),以免因?qū)嶒?yàn)而意外損失)

  • 結(jié)合作業(yè)#3,針對你的數(shù)據(jù)庫中的一個表,編寫簡單的數(shù)據(jù)查詢(查詢語句應(yīng)包括單個涉及非主屬性等值比較的查詢條件,設(shè)該非主屬性為A,具體屬性結(jié)合業(yè)務(wù)背景)和數(shù)據(jù)插入語句,程序應(yīng)能在終端或服務(wù)器以文件形式記錄每次數(shù)據(jù)讀寫操作的耗時(shí)。
  • 無索引壓力測試實(shí)驗(yàn):設(shè)定該表的數(shù)據(jù)插入頻率(如100條/秒),至少有1臺以上終端以并發(fā)的形式插入數(shù)據(jù),運(yùn)行一段時(shí)間使數(shù)據(jù)達(dá)到百萬條級以上,數(shù)據(jù)規(guī)模上限自定。同時(shí)使用1臺終端每秒并發(fā)執(zhí)行一次查詢操作,要求查詢條件不包含主碼,且不存在針對屬性A建立的非聚集索引。
  • 有索引壓力測試:清空原有數(shù)據(jù),實(shí)驗(yàn)內(nèi)容同上,但除主鍵索引外,需要針對屬性A建立非聚集索引,重新執(zhí)行一輪壓力測試。
  • 選做:加大數(shù)據(jù)插入與查詢頻率,觀察你的服務(wù)器和不同設(shè)計(jì)方案的壓力承受能力。注意控制規(guī)模以免導(dǎo)致硬盤工作空間溢出。
  • 分析實(shí)驗(yàn)數(shù)據(jù),制作圖表,比較有索引和無索引的情況下,插入時(shí)間與查詢時(shí)間隨數(shù)據(jù)量增加的變化情況,以及在相同資源條件下比較有索引和無索引的情況下同一指標(biāo)隨數(shù)據(jù)量增加的變化情況,分析導(dǎo)致實(shí)驗(yàn)結(jié)果的原因。
    實(shí)驗(yàn)過程如下:
    1)
  • 首先,選取之前建立的數(shù)據(jù)庫,選擇wechat_tbl表(也就是用戶表)
  • 編寫簡單的查詢語句為:select*from wechat_tbl where wechat_password=‘oqXKaJ’(查詢密碼為oqXKaJ的用戶),其中wechat_password為非主屬性滿足題目要求。
  • 數(shù)據(jù)插入語句我選擇由java程序?qū)崿F(xiàn),設(shè)計(jì)程序語言讀取記錄每次查詢和插入所需要的時(shí)間,并且能夠?qū)⒔Y(jié)果存入txt文件中。程序運(yùn)行結(jié)果如下圖所示:(代碼已放入壓縮包中)
  • 2)無索引壓力測試實(shí)驗(yàn):

  • 在代碼中通過Thread.sleep(1000)控制插入頻率和查詢頻率(題目要求為插入頻率100條/秒,查詢頻率為1/秒)

  • 查詢所插入和查詢的表中存在的索引,確定不存在針對wechat_password建立的非聚集索引,查詢結(jié)果如下圖所示:

  • 將寫好的java運(yùn)行一段時(shí)間使數(shù)據(jù)達(dá)到百萬條級以上(在java內(nèi)通過循環(huán)實(shí)現(xiàn)),數(shù)據(jù)上限我設(shè)的是100萬條,運(yùn)行寫好的程序,將每秒每插入100條數(shù)據(jù)的時(shí)間以及查詢一次的時(shí)間記錄到文本中(文本文件已放入壓縮包),對這10000條數(shù)據(jù)使用Excel 對每100條數(shù)據(jù)求平均值,進(jìn)行擬合得出隨數(shù)據(jù)增加插入時(shí)間變化圖表以及查詢時(shí)間變化圖表如下:

  • 3) 有索引壓力測試:

  • 清空原有數(shù)據(jù),實(shí)驗(yàn)內(nèi)容同上,wechat_password建立非聚集索引,重新執(zhí)行一輪壓力測試,過程如下圖所示:
  • 可見數(shù)據(jù)量較大時(shí),創(chuàng)建索引的時(shí)間也比較長;

    上圖為刪掉增加的100萬條數(shù)據(jù);

    重新開始運(yùn)行程序
    2. 數(shù)據(jù)上限依然設(shè)的是100萬條,運(yùn)行寫好的程序,將每秒每插入100條數(shù)據(jù)的時(shí)間以及查詢一次的時(shí)間記錄到文本中(文本文件已放入壓縮包),對這10000條數(shù)據(jù)使用Excel 對每100條數(shù)據(jù)求平均值,進(jìn)行擬合得出隨數(shù)據(jù)增加插入時(shí)間變化圖表以及查詢時(shí)間變化圖表如下:

    4) 分析實(shí)驗(yàn)數(shù)據(jù):

  • 有索引和無索引的情況下,插入時(shí)間與查詢時(shí)間隨數(shù)據(jù)量增加的變化情況對比圖在上方展示,由此分析:
    無索引的情況下:
    首先,插入時(shí)間每插入100條數(shù)據(jù),所需要的時(shí)間都大致在170ms左右波動,并且隨數(shù)據(jù)量的增加,由圖所示趨勢線可知在不斷增長。
    其次,數(shù)據(jù)庫在多于100萬條數(shù)據(jù)的情況下,查詢時(shí)間由開始的1ms,到100萬條數(shù)據(jù)時(shí)的400ms,查詢所需時(shí)間隨插入數(shù)據(jù)量的增加,查詢所需時(shí)間呈增長趨勢,大致平均每10萬條數(shù)據(jù)查詢所需要的時(shí)間就要增加40ms。
    有索引的情況下:
    首先,相比無索引的情況,插入數(shù)據(jù)時(shí)間大致在270Ms左右,隨數(shù)據(jù)量的增加,由圖所示趨勢線可知也在不斷增長。每次查詢的時(shí)間大大減少,100萬數(shù)據(jù)時(shí)查詢時(shí)間由之前的無索引狀態(tài)下的400ms變成現(xiàn)在的1ms左右,其查詢速度顯著提高,并且隨著插入數(shù)據(jù)的增加,查詢時(shí)間并沒有明顯的增加,一直保持在1Ms左右,可見加入索引之后大大提高了查詢的速度。

  • 相同數(shù)據(jù)量情況下
    經(jīng)統(tǒng)計(jì)插入一百萬條數(shù)據(jù)無索引一共需要1765578ms,也就是1765.578s,而有索引情況下插入一百萬條數(shù)據(jù)需要3260311ms,也就是3260.311s,比較發(fā)現(xiàn)二者時(shí)間差接近兩倍。
    有索引在相同數(shù)據(jù)量情況下的查詢時(shí)間在數(shù)據(jù)量少時(shí)與無索引查詢時(shí)間相差不大,但是在數(shù)據(jù)量大時(shí),產(chǎn)生了較大的差異,無索引查詢時(shí)間呈線性增長趨勢,而有索引并無增長趨勢,而控制在一個常數(shù)范圍。
    另外,有索引的插入速度在相同數(shù)據(jù)量情況下,每插入100條數(shù)據(jù)比無索引慢了大概100ms左右,且隨數(shù)據(jù)量的增加,差異值一直控制在這個范圍內(nèi),沒有明顯增長。

  • 實(shí)驗(yàn)結(jié)果分析:
    有上面結(jié)果可知,添加索引后使查詢速度增加了,卻使插入速度降低了,索引能讓數(shù)據(jù)庫查詢數(shù)據(jù)的速度上升, 而使寫入數(shù)據(jù)的速度下降,原因很簡單的, 因?yàn)槠胶鈽溥@個結(jié)構(gòu)必須一直維持在一個正確的狀態(tài), 增刪改數(shù)據(jù)都會改變平衡樹各節(jié)點(diǎn)中的索引數(shù)據(jù)內(nèi)容,破壞樹結(jié)構(gòu), 因此,在每次數(shù)據(jù)改變時(shí), DBMS必須去重新梳理樹(索引)的結(jié)構(gòu)以確保它的正確,這會帶來不小的性能開銷,也就是為什么索引會給查詢以外的操作帶來副作用的原因。
    對于用到的非聚簇索引,除了聚集索引以外的索引都是非聚集索引,細(xì)分一下非聚集索引,分成普通索引,唯一索引,全文索引。非聚集索引和聚集索引一樣, 同樣是采用平衡樹作為索引的數(shù)據(jù)結(jié)構(gòu)。索引樹結(jié)構(gòu)中各節(jié)點(diǎn)的值來自于表中的索引字段, 假如給wechat_name表的wechat_password字段加上索引 ,那么索引就是由wechat_password字段中的值構(gòu)成,在數(shù)據(jù)改變時(shí), DBMS需要一直維護(hù)索引結(jié)構(gòu)的正確性。如果給表中多個字段加上索引 , 那么就會出現(xiàn)多個獨(dú)立的索引結(jié)構(gòu),每個索引(非聚集索引)互相之間不存在關(guān)聯(lián)。非聚集索引和聚集索引的區(qū)別在于, 通過聚集索引可以查到需要查找的數(shù)據(jù), 而通過非聚集索引可以查到記錄對應(yīng)的主鍵值 , 再使用主鍵的值通過聚集索引查找到需要的數(shù)據(jù)。
    每次給字段建一個新索引, 字段中的數(shù)據(jù)就會被復(fù)制一份出來, 用于生成索引。 因此,給表添加索引,會增加表的體積,占用磁盤存儲空間。這也就解釋了實(shí)驗(yàn)中添加索引后插入速度降低的原因。
    經(jīng)過本次實(shí)驗(yàn),在以后創(chuàng)建表格時(shí),盡量保證將主要的數(shù)據(jù)都插入之后,再添加索引,避免在添加索引之后進(jìn)行數(shù)據(jù)插入,以保證效率最高。
    附錄:(壓力測試java代碼)

  • package testmysql;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.Writer;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.Date;
    import java.util.Random;

    public class TestMysql {
    static int k;
    public static void main(String[] arg){
    Connection conn;
    PreparedStatement stmt;
    String driver = “com.mysql.jdbc.Driver”;
    String url = “jdbc:mysql://localhost:3306/wechat?useSSL=false&serverTimezone=Asia/Shanghai”;
    String user = “root”;
    String password = null;
    String sql = “insert into wechat_tbl values (?,?,?,?,?,?,?)”;
    String sql2 = “select*from wechat_tbl where wechat_password=‘oqXKaJ’”;
    k=101;
    Boolean result = false;
    File file =new File(“D:\soft\2.txt”);
    try{
    Writer out =new FileWriter(file);
    int count = 0;
    while(!result) {

    try{Class.forName(driver);conn = DriverManager.getConnection(url, user, password);stmt = (PreparedStatement) conn.prepareStatement(sql);Thread.sleep(1000); //設(shè)置暫停的時(shí)間 1秒count ++ ;System.out.println(new Date() + "--循環(huán)執(zhí)行第" + count + "次");long saa=0;for(int i=0;i<100;i++){stmt.setInt(1, i+k);stmt.setString(2, TestMysql.getRandomString(7));stmt.setString(3, TestMysql.getRandomString(5));if(i%2==0){stmt.setString(4, "boy");}else{stmt.setString(4, "girl");}stmt.setString(5, TestMysql.getRandomString(6));stmt.setString(6, "china");stmt.setString(7, TestMysql.getRandomString(9));long spp = System.currentTimeMillis();stmt.executeUpdate();long sqq = System.currentTimeMillis();saa += sqq-spp;}k=k+101;long midTime = System.currentTimeMillis();stmt = (PreparedStatement) conn.prepareStatement(sql2);stmt.executeQuery();long endTime =System.currentTimeMillis();long usedTime2 = (endTime-midTime); System.out.println(saa+"ms "+usedTime2+"ms");out.write(saa+"ms "+usedTime2+"ms\n");if (count == 10000) {result = true;out.close();break ;}}catch (InterruptedException e) {e.printStackTrace();} catch (ClassNotFoundException e) {// TODO 自動生成的 catch 塊e.printStackTrace();} catch (SQLException e) {// TODO 自動生成的 catch 塊e.printStackTrace();}}}catch(IOException e){e.printStackTrace();}} public static String getRandomString(int length) {Random random = new Random();StringBuffer sb = new StringBuffer();for (int i = 0; i < length; i++) {int number = random.nextInt(3);long result = 0;switch (number) {case 0:result = Math.round(Math.random() * 25 + 65);sb.append(String.valueOf((char) result));break;case 1:result = Math.round(Math.random() * 25 + 97);sb.append(String.valueOf((char) result));break;case 2:sb.append(String.valueOf(new Random().nextInt(10)));break;}}return sb.toString(); }

    總結(jié)

    以上是生活随笔為你收集整理的数据库压力测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。