数据库压力测试
一、 存儲過程和觸發器實驗
1)單表或多表查詢 2)數據插入 3)數據刪除 4)數據修改
1)單表查詢,結果如下:
–查詢u_id大于輸入的num的
drop procedure if exists sl;
– 如果存在就drop
delimiter //
– 定義為碰到//才表示語句結束
create procedure sl(num int)
begin
select * from User_tbl where u_id > num;
end //
delimiter ;
– 定義為碰到;表示語句結束
call sl(5);
多表查詢結果如下:
查找u_id為輸入的n的用戶的朋友圈內容和他的真實姓名
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)數據插入
drop procedure if exists sp1;
– 如果存在就drop
delimiter //
– 定義為碰到//才表示語句結束
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’, name, tname, sex, ‘null’, ‘null’, ‘null’);
select * from user_tbl;
end //
delimiter ;
call sp1(‘www’,‘32ewew’,‘wan’,‘dongyu’,‘男’);
3)數據刪除,結果如下:
– 數據刪除
drop procedure if exists del;
– 如果存在就drop
delimiter //
– 定義為碰到//才表示語句結束
create procedure del(id int)
begin
delete from Circlemsg_tbl where p_id = id;
select * from Circlemsg_tbl;
end //
delimiter ;
call del(3);
– 定義為碰到;表示語句結束
call del();
– 定義為碰到;表示語句結束
4)數據修改,結果如下:
drop procedure if exists up;
– 如果存在就drop
delimiter //
– 定義為碰到//才表示語句結束
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’);
– 定義為碰到;表示語句結束
2.通過ODBC、OLEDB、JDBC或任意其他的途徑,在前端程序(C/S或B/S模式)中調用所實現的后臺存儲過程。
我使用的是JDBC實現在前端程序調用數據庫后臺存儲過程,代碼過長,放入壓縮包中。(網頁采用的是Jquery架構),網頁整體頁面如下:
數據查詢:(輸入用戶名,點擊查詢按鈕即可查詢到數據庫中該用戶的信息并在頁面顯示出來),結果如下圖:
數據插入操作 插入用戶信息,點擊頁面的添加按鈕,在動態彈出的表單中輸入用戶信息,點擊確認,即可完成添加,添加結果自動返回顯示,操作界面如下圖:
數據刪除操作 點擊每個用戶欄對應的最右邊的刪除鏈接,即可實現對該用戶的刪除操作,刪除完成后自動顯示當前數據庫的狀態結果。如下圖所示:
數據修改操作,點擊每個用戶欄對應的最右邊的修改密碼鏈接,跳轉到修改密碼的頁面,輸入新的密碼,即可實現對該用戶的密碼修改操作,如下圖所示:
跳轉:
3.在你的案例場景中,分別設計并實現一個由數據插入、數據更新、數據刪除所引發的觸發器(前觸發或后觸發都可以),測試觸發器執行效果。
–創建記錄微信用戶的表wechat_count,默認為0
CREATE TABLE wechat_count (
wechat_count INT(11) DEFAULT 0
);
INSERT INTO wechat_count VALUES(0);
select * from wechat_count;
1) 數據插入
–創建簡單觸發器,在向wechat_tbl表INSERT數據時,wechat_count增加
CREATE TRIGGER trigger_insert
AFTER INSERT
ON user_tbl FOR EACH ROW
UPDATE wechat_count SET wechat_count=wechat_count+1;
call sp1(‘weqqw’,‘3121w’,‘anan’,‘pengyuyan’,‘男’);;
select * from wechat_count;
結果如下:
2) 數據更新
–數據更新
–創建簡單觸發器,在向wechat_tbl表UPDATA數據時,
–創建記錄數據更新技術的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;
–驗證觸發器
delimiter ;
call up(‘2wed’,‘111121311’);
select * from user_tbl;
select * from updata_count;
3) 數據刪除
–數據刪除
–創建簡單觸發器,在向wechat_tbl表DELETE數據時,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;
二、 壓力測試與索引實驗(注意提前備份好機器上的關鍵數據,以免因實驗而意外損失)
實驗過程如下:
1)
2)無索引壓力測試實驗:
在代碼中通過Thread.sleep(1000)控制插入頻率和查詢頻率(題目要求為插入頻率100條/秒,查詢頻率為1/秒)
查詢所插入和查詢的表中存在的索引,確定不存在針對wechat_password建立的非聚集索引,查詢結果如下圖所示:
將寫好的java運行一段時間使數據達到百萬條級以上(在java內通過循環實現),數據上限我設的是100萬條,運行寫好的程序,將每秒每插入100條數據的時間以及查詢一次的時間記錄到文本中(文本文件已放入壓縮包),對這10000條數據使用Excel 對每100條數據求平均值,進行擬合得出隨數據增加插入時間變化圖表以及查詢時間變化圖表如下:
3) 有索引壓力測試:
可見數據量較大時,創建索引的時間也比較長;
上圖為刪掉增加的100萬條數據;
重新開始運行程序
2. 數據上限依然設的是100萬條,運行寫好的程序,將每秒每插入100條數據的時間以及查詢一次的時間記錄到文本中(文本文件已放入壓縮包),對這10000條數據使用Excel 對每100條數據求平均值,進行擬合得出隨數據增加插入時間變化圖表以及查詢時間變化圖表如下:
4) 分析實驗數據:
有索引和無索引的情況下,插入時間與查詢時間隨數據量增加的變化情況對比圖在上方展示,由此分析:
無索引的情況下:
首先,插入時間每插入100條數據,所需要的時間都大致在170ms左右波動,并且隨數據量的增加,由圖所示趨勢線可知在不斷增長。
其次,數據庫在多于100萬條數據的情況下,查詢時間由開始的1ms,到100萬條數據時的400ms,查詢所需時間隨插入數據量的增加,查詢所需時間呈增長趨勢,大致平均每10萬條數據查詢所需要的時間就要增加40ms。
有索引的情況下:
首先,相比無索引的情況,插入數據時間大致在270Ms左右,隨數據量的增加,由圖所示趨勢線可知也在不斷增長。每次查詢的時間大大減少,100萬數據時查詢時間由之前的無索引狀態下的400ms變成現在的1ms左右,其查詢速度顯著提高,并且隨著插入數據的增加,查詢時間并沒有明顯的增加,一直保持在1Ms左右,可見加入索引之后大大提高了查詢的速度。
相同數據量情況下
經統計插入一百萬條數據無索引一共需要1765578ms,也就是1765.578s,而有索引情況下插入一百萬條數據需要3260311ms,也就是3260.311s,比較發現二者時間差接近兩倍。
有索引在相同數據量情況下的查詢時間在數據量少時與無索引查詢時間相差不大,但是在數據量大時,產生了較大的差異,無索引查詢時間呈線性增長趨勢,而有索引并無增長趨勢,而控制在一個常數范圍。
另外,有索引的插入速度在相同數據量情況下,每插入100條數據比無索引慢了大概100ms左右,且隨數據量的增加,差異值一直控制在這個范圍內,沒有明顯增長。
實驗結果分析:
有上面結果可知,添加索引后使查詢速度增加了,卻使插入速度降低了,索引能讓數據庫查詢數據的速度上升, 而使寫入數據的速度下降,原因很簡單的, 因為平衡樹這個結構必須一直維持在一個正確的狀態, 增刪改數據都會改變平衡樹各節點中的索引數據內容,破壞樹結構, 因此,在每次數據改變時, DBMS必須去重新梳理樹(索引)的結構以確保它的正確,這會帶來不小的性能開銷,也就是為什么索引會給查詢以外的操作帶來副作用的原因。
對于用到的非聚簇索引,除了聚集索引以外的索引都是非聚集索引,細分一下非聚集索引,分成普通索引,唯一索引,全文索引。非聚集索引和聚集索引一樣, 同樣是采用平衡樹作為索引的數據結構。索引樹結構中各節點的值來自于表中的索引字段, 假如給wechat_name表的wechat_password字段加上索引 ,那么索引就是由wechat_password字段中的值構成,在數據改變時, DBMS需要一直維護索引結構的正確性。如果給表中多個字段加上索引 , 那么就會出現多個獨立的索引結構,每個索引(非聚集索引)互相之間不存在關聯。非聚集索引和聚集索引的區別在于, 通過聚集索引可以查到需要查找的數據, 而通過非聚集索引可以查到記錄對應的主鍵值 , 再使用主鍵的值通過聚集索引查找到需要的數據。
每次給字段建一個新索引, 字段中的數據就會被復制一份出來, 用于生成索引。 因此,給表添加索引,會增加表的體積,占用磁盤存儲空間。這也就解釋了實驗中添加索引后插入速度降低的原因。
經過本次實驗,在以后創建表格時,盡量保證將主要的數據都插入之后,再添加索引,避免在添加索引之后進行數據插入,以保證效率最高。
附錄:(壓力測試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) {
總結
- 上一篇: Python批量裁剪图形外围空白区域
- 下一篇: mysql笔记--03DML