之前寫過一個FunTester框架對Redis進行幾種常見API進行性能測試的系列文章,今天如約開始寫FunTester框架對MySQL常用功能的性能測試。
我們來回顧一些Redis性能測試的文章:
MySQL系列文章預計分兩期,分別是增刪、改查,進行簡單的SQL語句操作,如在實際工作中用到,需要自行實現SQL語句的參數化,滿足業務需求。
MySQL是我本地的服務,用的也是本機,本次測試只演示常見增刪改查功能的性能測試,不測試MySQL服務性能,也不設置索引等參數。後續等我學完Go語言的gorm框架,我再寫一篇Go語言的MySQL性能測試文章分享。
準備工作省略不寫,無非就是起個服務,建個庫表,主要name和age兩個欄位,一個字符串一個整型數字。
insert這個在工作中用到的不少,估計在造數據的時候用到會比較多。這裡使用單條數據執行的方式。
腳本用到SQL:INSERT INTO funtesters (name,age) VALUES (\"fun${StringUtil.getString(10)}\",${getRandomInt(100)});
翻譯成Java:"INSERT INTO funtesters (name,age) VALUES (\"fun"+StringUtil.getString(10)+"\","+getRandomInt(100)+");"
參數化:通過隨機字符串和隨機數字構成,由於本項目沒有去重需求,所以沒有採取唯一變量的方式。
腳本用例
/**
* MySQL insert語句實踐
*/
class MysqlInsert extends SqlBase {
static final String url = "jdbc:mysql://localhost:3306/funtester?useUnicode=true&characterEncoding=utf-8&useOldAliasMetadataBehavior=true&useSSL=false"
static final int thread = 20
static final int times = 10000
public static void main(String[] args) {
RUNUP_TIME = 0
def task = []
thread.times {
task << new FunTester()
}
new Concurrent(task, "FunTester框架測試MySQL").start()
FunLibrary.testOver()
}
private static class FunTester extends FixedThread {
def connection = getConnection(url, "root", "root123456")
def statement = getStatement(connection)
FunTester() {
super(null, times, true)
}
@Override
protected void doing() throws Exception {
statement.execute("INSERT INTO funtesters (name,age) VALUES (\"fun${StringUtil.getString(10)}\",${getRandomInt(100)});")
}
@Override
protected void after() {
super.after()
close(connection, statement)
}
@Override
FixedThread clone() {
return new FunTester(limit)
}
}
}
測試結果~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
> {
> ① . "rt":1,
> ① . "failRate":0.0,
> ① . "threads":20,
> ① . "deviation":"13.1%",
> ① . "errorRate":0.0,
> ① . "executeTotal":198907,
> ① . "qps2":17380.898287312128,
> ① . "total":198907,
> ① . "qps":20000.0,
> ① . "startTime":"2021-11-17 15:32:52",
> ① . "endTime":"2021-11-17 15:33:03",
> ① . "mark":"FunTester框架測試MySQL171532",
> ① . "table":"eJzj5VIgCNxK80JSi0tSi54tbHs2b9uzrd0v1k/1rQwO9FEwMlAoyShKTUwhbAovFy9+u4JSiwvy84pTFUIyc1OtFCp0i1OLMhNzFPJKc3UUKnVzU1MyE/MI2UHYHQoKuZl5ChDTrAwUcot1chMrrIyADGL0EvQFOeDRtA4gwkuN2jpq66ito7aO2jpq68iwlQilQ4wa9dnQo0Z9NvSoUZ8NPWrUZ0OPGvXZ0KNGfTb0qFGfDT1qOPsMAApg90I="
> }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~看QPS還挺快的,哈哈。
delete刪除這個比較麻煩,因為這些數據刪了就沒了。如果採取如何對消息隊列做性能測試這個方案,有點大材小用,我這裡就用隨機名稱作為刪除數據的依據,執行先insert再delete的測試方案。
測試用例/**
* MySQL insert語句實踐
*/
class MysqlDelete extends SqlBase {
static final String url = "jdbc:mysql://localhost:3306/funtester?useUnicode=true&characterEncoding=utf-8&useOldAliasMetadataBehavior=true&useSSL=false"
static final int thread = 10
static final int times = 100
public static void main(String[] args) {
RUNUP_TIME = 0
def task = []
thread.times {
task << new FunTester()
}
new Concurrent(task, "FunTester框架測試MySQL").start()
FunLibrary.testOver()
}
private static class FunTester extends FixedThread {
def connection = getConnection(url, "root", "root123456")
def statement = getStatement(connection)
FunTester() {
super(null, times, true)
}
@Override
protected void doing() throws Exception {
String name = "fun${StringUtil.getString(10)}"
statement.execute("INSERT INTO funtesters (name,age) VALUES (\"$name\",${getRandomInt(100)});")
statement.execute("DELETE FROM funtesters WHERE name = \"$name\";")
}
@Override
protected void after() {
super.after()
close(connection, statement)
}
@Override
FixedThread clone() {
return new FunTester(limit)
}
}
}
測試結果~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~
> {
> ① . "rt":1354,
> ① . "failRate":0.0,
> ① . "threads":10,
> ① . "deviation":"0.47%",
> ① . "errorRate":0.0,
> ① . "executeTotal":1000,
> ① . "qps2":7.3508872520913275,
> ① . "total":1000,
> ① . "qps":7.385524372230428,
> ① . "startTime":"2021-11-17 15:51:41",
> ① . "endTime":"2021-11-17 15:53:57",
> ① . "mark":"FunTester框架測試MySQL171551",
> ① . "table":"eJwBLwDQ/+aVsOaNrumHj+WkquWwkSzml6Dms5Xnu5jlm74hIOW6lOW9k+Wkp+S6jiAxMDI0/eodgA=="
> }
~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~ JSON ~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~~☢~可以看到,受delete方法的影響,性能下降挺多的。
敬請期待下期的select和update以及未來可能的Go語言實踐,Java和Go的HTTP客戶端和服務端對比壓測已經在路上了。
「歡迎關注FunTester,Have Fun ~ Tester !」