SQLTest系列之INSERT語句測試
場景引入
菜鳥不斷又猛又持久的給老鳥驚喜以後,老鳥開始不斷的折騰菜鳥:“鳥,你研究下有沒有一款可以測試MSSQL Server的工具吧?”。
“這還不簡單,用Red Gate的SQLTest唄”,於是菜鳥開始了工具的研究之旅:“要不,今天就分享下SQLTest之Insert語句測試吧”。
SQLTest簡介
領了任務的菜鳥,由於之前對這個工具有所瞭解,所以還是比較輕車熟路的。讓我們先來看看SQLTest是幹什麼的吧。
SQLTest是一款簡單易用,非常容易上手的SQL Server效能、壓力和單元測試工具。它既可以測試本地環境的SQL Server工作負載,也可以測試雲環境的SQL Server服務。
SQLTest一鍵安裝
SQLTest就是一個簡單的SQL Server測試工具,所以,它的安裝過程也簡單。官方推薦一鍵安裝,簡單到令人髮指的地步。
下載地址:
http://www.sqltest.org/Download
測試環境
在測試之前,菜鳥彙總自己的測試環境資訊:
CPU:4 cores
Memory:4 GB
Disk: SSD
SQL Server: SQL Server 2008R2 SP2
SQLTest INSERT語句測試
老實講,上面都不重要,看好了,這裡才是本文的重點:如何使用SQLTest來測試INSERT的效率呢?如何測試INSERT語句在不同執行緒數量下的效率?不同的資料型別選擇對INSERT效率的影響如何?
這裡虛擬一個場景,假設我們有一張名為Orders的訂單表,我們會根據Orders的主鍵資料型別的不同來測試INSERT的效率。
INT IDENTITY
建立測試資料庫和Orders表
use master;
IF DB_ID(`SQLTestDemo`) IS NULL
CREATE DATABASE SQLTestDemo
go
use SQLTestDemo
go
IF OBJECT_ID(`Orders`,`U`) IS NOT NULL
BEGIN
TRUNCATE TABLE Orders
DROP TABLE Orders
END
GO
CREATE TABLE Orders (
OrderID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED
, OrderDate datetime
, CustomerID int
, SourceID int
, StatusID int
, Amount decimal (18, 2)
, OrderDetails char(7000)
)
GO
所有準備工作就緒,菜鳥迫不及待的開始測試了,開啟SQLTest,設定SQLClient Connection String
Data Source=(local);Database=SQLTestDemo;Integrated Security=true;Pooling=false
SQL Command
insert into Orders values (getdate (), 1, 1, 1, 1, replicate (`a`, 7000))
go
Number of Threads
點選Start Current按鈕,測試時間10秒後,得到如下截圖:
1個執行緒執行10秒鐘,迭代了12471次,每次迭代消耗資料庫時間0.000秒。(由於這裡精確到千分之一秒,也就是一毫秒,說明每次迭代耗時少於1毫秒)。
現在我們分別將執行緒數調整為2,4,8,16,32,64,128,256來測試,為了測試的相對準確性,請在測試之前執行“建立測試資料庫和Orders表”中的程式碼,重新建立Orders表。SQLTest返回結果的設定方法如下:Settings => Workload Settings
測試完畢後,我們可以得到如下表格資料:
將這些資料繪製成直方圖和折線圖:
從這個圖中,可以很直觀的得出如下結論:
- 從吞吐量來看:無輸出結果方式遠遠大於有輸出結果方式,前者是後者的兩倍還多;
- 從資料庫平均耗時來看:無輸出結果效率也遠遠高於有輸出結果方式,後者是前者的兩倍;
- 從執行緒數量來看:並不是執行緒數開得越多,SQL Server吞吐量越大,效率越高;無論是有輸出結果方式還是無輸出結果方式,併發8到16個執行緒SQL Server的吞吐量達到最大,效率最高;
注意:
最後一個結論不一定適用於所有的SQL Server,因為這個和SQL Server的版本,機器的CPU,Memory,磁碟等有密切的關係,使用者在得到這個值之前需要自己嚴格測試。
提供INT值
完成了主鍵值INT IDENTITY的測試後,菜鳥陷入了疑惑:每個執行緒如何插入不同的值呢?於是有了這個測試方法:
use SQLTestDemo
go
IF OBJECT_ID(`Orders`,`U`) IS NOT NULL
begin
truncate table Orders
drop table Orders
end
go
create table Orders (OrderID int primary key clustered
, OrderDate datetime
, CustomerID int
, SourceID int
, StatusID int
, Amount decimal (18, 2)
, OrderDetails char (7000)
)
go
讓每個執行緒生成不同的OrderID,我們可以使用SQLTest_Thread來代替執行緒數,SQLTest_Iteration代替迭代次數,最終將SQL Command修改為:
insert into Orders values (({SQLTest_Thread} * 100000) + {SQLTest_Iteration}, getdate(), 1, 1, 1, 1, replicate (`a`, 7000))
go
UNIQUEIDENTIFIER with NEWID()
測試方法類似於“INT IDENTITY”章節,只是Orders表結構和SQL Command不一致。
use SQLTestDemo
go
IF OBJECT_ID(`Orders`,`U`) IS NOT NULL
begin
truncate table Orders
drop table Orders
end
go
create table Orders (
OrderID uniqueidentifier not null default newid () primary key clustered
, OrderDate datetime
, CustomerID int
, SourceID int
, StatusID int
, Amount decimal (18, 2)
, OrderDetails char (7000))
go
SQL Command
insert into Orders values (NEWID(),getdate (), 1, 1, 1, 1, replicate (`a`, 7000))
go
UNIQUEIDENTIFIER with NEWSEQUENTIALID()
同上,測試方法類似於“INT IDENTITY”章節,只是Orders表結構和SQL Command不一致。
use SQLTestDemo
go
IF OBJECT_ID(`Orders`,`U`) IS NOT NULL
BEGIN
TRUNCATE TABLE Orders
DROP TABLE Orders
END
GO
CREATE TABLE Orders (
OrderID uniqueidentifier default newsequentialid () primary key clustered
, OrderDate datetime
, CustomerID int
, SourceID int
, StatusID int
, Amount decimal (18, 2)
, OrderDetails char (7000))
GO
SQL Command
insert into Orders(OrderDate,CustomerID,SourceID,StatusID,Amount,OrderDetails) values (getdate (), 1, 1, 1, 1, replicate (`a`, 7000))
go
總結
將四種資料型別在No Result輸出情況彙總統計如下表:
做一個漂亮炫酷的圖表出來對比下:
從這個圖示,我們可以發現如下規律:
- 從吞吐量角度來看:所有資料型別,併發量聚集在8到16時,INSERT操作吞吐量達到最大值;
- 吞吐量表現最好的是int identity資料型別和uniqueidentifier + newsequentialid做為主鍵的表;
- 從資料庫平均耗時角度:所有資料型別,併發量在8到16時,INSERT操作的平均時間消耗最小,接近64個執行緒時,平均耗時會急劇上升;
- 平均耗時表現最好的是int identity和Newsequentialid型別。
從結果來看,UNIQUEIDENTIFIER + NEWSEQUENTIALID和INT IDENTITY效能和吞吐量表現都非常好,我們到底該選擇哪一個更好一些呢? 我的結論是選擇IDENTITY屬性的數字型別欄位做為主鍵,因為它佔的空間更小,INT為4個位元組,BIGINT為8個位元組而UNIQUEIDENTIFIER 佔了36個位元組。
寫在最後
老鳥看完菜鳥的研究報告,讚不絕口:“不錯啊,今天的最好表現就是明天對你的最低要求,SQLTest INSERT如何做引數化測試啊?”。
菜鳥賣起了關子:“鳥哥,預知後事如何,且聽下回分解”。
相關文章
- SQLite Insert 語句SQLite
- insert into select語句與select into from語句
- KunlunDB功能之insert/update/delete...returning語句delete
- insert all和insert first語句的用法
- 【SQL】9 SQL INSERT INTO 語句SQL
- TiDB 原始碼閱讀系列文章(十六)INSERT 語句詳解TiDB原始碼
- 教你使用SQLite-insert語句SQLite
- [20181120]奇怪的insert語句.txt
- 【SQL】14 UNION 操作符、SELECT INTO 語句、INSERT INTO SELECT 語句、CREATE DATABASE 語句、CREATE TABLE 語句SQLDatabase
- 測試平臺系列(83) 前置條件支援Redis語句Redis
- SQLite語句(二):INSERT DELETE UPDATE SELECTSQLitedelete
- DBeaver如何生成select,update,delete,insert語句delete
- oracle-資料庫- insert 插入語句Oracle資料庫
- Linux下邏輯測試語句引數和流程控制語句 if語句Linux
- MySQL全文索引原始碼剖析之Insert語句執行過程MySql索引原始碼
- PostgreSQL的insert語句執行過程分析SQL
- flask之控制語句 if 語句與for語句Flask
- Exadata混合列壓縮功能與INSERT語句BF
- MySQL:一個簡單insert語句的大概流程MySql
- 輕量ORM-SqlRepoEx (四)INSERT、UPDATE、DELETE 語句ORMSQLdelete
- 【Golang 基礎系列十】Go 語言 條件語句之ifGolang
- 軟體測試培訓之:白盒測試的語句覆蓋法和判定覆蓋法
- INSERT...SELECT語句對查詢的表加鎖嗎
- 比CRUD多一點兒(二):基礎INSERT、SELECT語句
- PostgreSQL 原始碼解讀(14)- Insert語句(如何構造PlannedStmt)SQL原始碼
- 自學黑馬系列C++基礎之跳轉語句C++
- 過往記憶的專欄文章轉載:Hive insert into語句用法Hive
- Oracle exp dmp包檔案轉化為insert語句,extract dmp to sqlfileOracleSQL
- PostgreSQL 原始碼解讀(15)- Insert語句(執行過程跟蹤)SQL原始碼
- TPCH模型規範、測試說明及22條語句模型
- 軟體測試之資料庫測試技術系列七資料庫
- 二分搜尋樹系列之[ 插入操作 (insert) ]
- 二分搜尋樹系列之「 插入操作 (insert) 」
- python之判斷語句Python
- Mysql之查詢語句MySql
- springboot系列文章之使用單元測試Spring Boot
- 不同insert操作產生的undo的測試
- 【ASK_ORACLE】使用insert語句將普通錶轉換成分割槽表Oracle
- SQL語句寫到累了?試試GreenDAOSQL