第一篇:LoadRunner測試SQL語句性能
本次通過loadRunner錄制SQLServer介紹一下如何測試一個sql語句或存儲過程的執行性能。主要分如下幾個步驟完成:
第一步、測試準備
第二步、配置ODBC數據源
第三步、錄制SQL語句在Sql Server查詢分析器中的運行過程
第四步、優化錄制腳本,設置事務
第五步、改變查詢數量級查看SQL語句的性能
第六步、在controller中運行腳本
下面開始具體的介紹:
測試準備階段我們首先要確認測試數據庫服務器:我們可以在本地安裝SQL SERVER數據庫服務端及客戶端,也可以確定一臺裝好的SQL SERVER服務器。
接下來,準備測試數據:對數據庫測試時我們要考慮的不是SQL語句是否能夠正確執行,而是在某數量級的情況下SQL語句的執行效率及數據庫服務的運行情況,所以我們分別準備不同數量級的測試數據,即根據實際的業務情況預估數據庫中的記錄數,在本次講解中我們不考慮業務邏輯也不考慮數據表之間的關系,我們只建立一張表,并向此表中加入不同數量級的數據,如分別加入1000條、10000條、50000條、100000條數據查看某SQL語句的執行效率。在查詢分析器中運行如下腳本:
--創建測試數據庫
create database loadrunner_test;
use loadrunner_test
--創建測試數據表
create table test_table
(username varchar(50),sex int,age int,address varchar(100),post int)
--通過一段程序插入不同數量級的記錄,具體的語法在這里就不多說了
declare@iint
set@i=0
while@i<1000//循環1000次,可以根據測試數據情況改變插入條數
begin
BEGIN TRAN T1
insert into test_table(username,sex,age,address,post)values('戶瑞海'+cast(@i as varchar),@i-1,@i+1,'北京市和平里'+cast(@i as varchar)+'號',123456);
IF @@ERROR <> 0
begin
rollback;
select @@error
end
else
begin
commit;
set@i=@i+1
end
end
好了,執行完上述語句后,建立的數據表中已經有1000條記錄了,下面進行第二步的操作,配置ODBC數據源,為了能讓loadrunner能夠通過ODBC協議連接到我們建立的SQL SERVER數據路,我們需要在本機上建立ODBC數據源,建立方法如下:
控制面板—性能和維護—管理工具—數據源(ODBC)--添加,在列表中選擇SQL SERVER點擊完成,根據向導輸入數據源名稱,鏈接的服務器,下一步,輸入鏈接數據庫的用戶名和密碼,更改鏈接的數據庫,完成ODBC的配置,如果配置正確的話,在最后一步點擊“測試數據源”,會彈出測試成功的提示。
配置好ODBC數據源后就要錄制SQL語句在查詢分析器中的執行過程了:
1、打開loadrunner,選擇ODBC協議
2、在start recording中的application type 選擇win32 application;program to record中錄入SQL SERVER查詢分析器的路徑“..安裝目錄isqlw.exe”
3、開始錄制,首先通過查詢分析器登錄SQL SERVER,在打開的查詢分析器窗口中輸入要測試的SQL語句,如“select * from test_table;”
4、在查詢分析器中執行該語句,執行完成后,結束錄制
好了,現在就可以看到loadrunner生成的腳本了(由于腳本過長,在這里就不粘貼了,有需要的朋友可以加我QQ,我把腳本發給你們),通過這些語句,我們可以看出,登錄數據庫的過程、執行SQL語句的過程。
接下來,我們來優化腳本,我們分別為數據庫登錄部分和執行SQL語句的部分加一個事物,在增加一個double的變量獲取事務執行時間,簡單內容如下:
Action()
{double trans_time;//定義一個double型變量用來保存事務執行時間
lr_start_transaction(“sqserver_login”);//設置登錄事務的開始
lrd_init(&InitInfo, DBTypeVersion);//初始化鏈接(下面的都是loadrunner生成的腳本了,大家可以通過幫助查到每個函數的意思)
lrd_open_context(&Ctx1, LRD_DBTYPE_ODBC, 0, 0, 0);
lrd_db_option(Ctx1, OT_ODBC_OV_ODBC3, 0, 0);
lrd_alloc_connection(&Con1, LRD_DBTYPE_ODBC, Ctx1, 0 /*Unused*/, 0);
………………
trans_time=lr_get_transaction_duration(“sqserver_login”);//獲得登錄數據庫的時間lr_output_message(“sqserver_login事務耗時 %f 秒”, trans_time);//輸出該時間
lr_end_transaction(“sqserver_login”, LR_AUTO);//結束登錄事務
lr_start_transaction(“start_select”);//開始查詢事務
lrd_cancel(0, Csr2, 0 /*Unused*/, 0);
lrd_stmt(Csr2, “select * from test_table;rn”,-1, 1, 0 /*None*/, 0);//此句為執行的SQL lrd_bind_cols(Csr2, BCInfo_D42, 0);
lrd_fetch(Csr2,-10, 1, 0, PrintRow24, 0);
……………..trans_time=lr_get_transaction_duration(“start_select”);//獲得該SQL的執行時間
lr_output_message(“start_select事務耗時 %f 秒”, trans_time);//輸出該時間
lr_end_transaction(“start_select”, LR_AUTO);//結束查詢事務
優化后,在執行上述腳本后,就可以得到登錄到數據庫的時間及運行select * from test_table這條語句的時間了,當然我們也可以根據實際情況對該條語句進行參數化,可以測試多條語句的執行時間,也可以將該語句改為調用存儲過程的語句來測試存儲過程的運行時間。
接下來把該腳本在controller中運行,設置虛擬用戶數,設置集合點,這些操作我就不說了,但是值得注意的是,沒有Mercury 授權的SQL SERVER用戶license,在運行該腳本時回報錯,提示“You do not have a license for this Vuser type.Please contact Mercury Interactive to renew your license.”我們公司窮啊買不起loadrunner,所以我也無法繼續試驗,希望有license朋友們監控一下運行結果!
最起碼在VUGen中運行該腳本我們可以得到任意一個SQL語句及存儲過程的執行時間,如果我們測試的B/S結構的程序,我們也可以通過HTML協議錄制的腳本在CONTROLLER中監控SQL SERVER服務器的性能情況,這樣兩方面結合起來就可以對數據庫性能做一個完整的監控了。
第二篇:SQL語句性能優化
我也做了很長時間醫療軟件,也寫過不少sql優化,沒有詳細記錄下來,個人感覺下面轉載的更符合醫院醫療軟件實際業務,很認可大部分所寫的原則,固轉載過來,以作借鑒。軟件的根本還是在于更細更精,在于從客戶的實際使用考慮問題。
性能優化原則1:永遠避免困境
利用緩存把字典數據取到中間服務器或是客戶端替代直接sql查詢,如,門診醫生站把字典下載到客戶端,減少執行次數。
一次性取數據到客戶端,然后再逐條處理,而不是分次取數據,處理好一條數據再取下一條再處理。例:門診收費取hjcfmxk例子,原來是一張處方條明細都查詢一次,查詢后再處理,現改為一次把所有明細都取過來,然后一條條處理
盡量減少光標,看能不能用臨時表
性能優化原則2:kiss原則
對于where 條件中的左邊可以利用索引的字段Keep it simple stupid,左邊盡量避免用函數(substring,isnull,upper,lower),參加計算+,-*/
例子1:select * from ZY_BRFYMXK where substring(zxrq,1,8)='20081212‘
select * from ZY_BRFYMXK where zxrq between '2008121200' and '2008121224' 例子2:
select * from zy_detail_charge where SUBSTRING(patient_id,1,10)=
substring('000005090600',1,10)這句耗時30秒以上
select * from zy_detail_charge where patient_id like substring('000005090600',1,10)+'%' 這句耗時2秒以內
性能優化原則3:盡可能利用到索引
例:select * from ZY_BRFYMXK a(nolock),VW_LSYZK b(nolock)where a.syxh=3 and a.yzxh=b.xh and a.fylb=0
select * from ZY_BRFYMXK a(nolock),VW_LSYZK b(nolock)where a.syxh=3 and a.yzxh=b.xh and a.fylb=0 and b.syxh=3
性能優化原則4:or,避而遠之
對于索引字段盡力避免用or,普通字段可以用or,解決要么分解成多個sql,要么用業務規則避免,例:declare @rq1 ut_rq16,@syxh ut_syxh
select @rq1='20081201'
select @syxh=157
性能優化原則5:避免大批量數據取到前臺
例: select * from ZY_BRSYK cyrq between ‘20080901’ and ‘20081201‘,對于大醫院每天100多人,90天是9000條數據
性能優化原則6:事務,盡可能的短吧
所有計算、對臨時表的更新都應但放在事務外,事務中最好只有更新和插入正式表操作.因為事務中產生的鎖只有在commit tran是才會釋放。
性能優化原則7:熱表,留在最后吧
熱表是頻繁調用的表。如:sf_mzcfk,zy_brfymxk,bq_fyqqk.對于熱表盡量放在事務最后:這樣鎖的時間短。大家都堅持這樣,死鎖的可能性就小。如果都是熱表各個存儲過程更新表的順序應當一樣這樣可以避免死鎖
性能優化原則8:創建臨時表一定要避免在事務中作
如create #tempXX(…)
Select * into #tempXX from …
因為創建臨時表會鎖tempdb的系統表
例:生成#temp1放在事務內外,用sp_lock2 ‘’觀察結果
if object_id('tempdb..#temp1','U')is not null
drop table #temp1
begin tran
select * into #temp1 from ZY_BRSYK where ryrq>'20080901‘
select * from #temp1
waitfor delay '00:00:10'
commit
性能優化原則9:大的報表查詢避免與正常業務碰撞
如果沒有查詢服務器,那要在存儲過程中限制不能操作加上如:
declare @rq1 ut_rq16,@rq2 ut_rq16,@now ut_rq16
select @rq1=convert(varchar(8),getdate(),112)+'08:00:00'
select @rq1=convert(varchar(8),getdate(),112)+'11:30:00'
select @now=convert(char(8),getdate(),112)+convert(char(8),getdate(),8)
if @now>@rq1 and @now<@rq2
begin
select '上午繁忙時間段不能作此查詢'
return
end
性能優化原則10:存儲過程避免大的if…else…
這個常出項在業務相同表不同的存儲過程中,因為這樣常到if …else …原來醫技接口中很多這種存儲過程,當時把門診住院業務放在一個存儲過程中。這樣最大的問題是sql server會根據sql語句來compile存儲,這個過程會生成優化計劃,決定用那個索引。如果存儲過程用到門診表compile一下,到用到住院表是發現不對,又會compile一下,這樣不停compile.compile很號時間要1-2秒,而且一個存儲過成在compile是,所有調用這個存儲過程的進程都要在排隊等候,因為他會獨占鎖這個存儲過程
例:usp_yjjk_getwzxxm_old.sql,后改為:
usp_yjjk_getwzxxm.sql, usp_yjjk_getwzxxm_mz.sql,usp_yjjk_getwzxxm_zy.sql
性能優化原則11:進攻是最好的防守
在普通編程語句對于數據校驗總是用防守辦法先判斷,后再作相應處理。而在sql中先處理再判斷性能會好很多。
--更新藥品庫存。
If exists(select 1 from YK_YKZKC WHERE idm=100 and kcsl>50)
begin
update YK_YKZKC set kcsl=kcsl-50 where idm=100
End
Else begin
rollback tran
Select ‘F庫存不夠’
return
end
--改為
update YK_YKZKC set kcsl=kcsl-50 where idm=100 and kcsl>50
If @@rowcount<=0
Begin
Rollbakc tran
Select ‘F庫存不夠’
end
--取未執行的醫技項目,日表沒有數據就到年表中查找
if exists(select a.* from SF_MZCFK a(nolock),SF_CFMXK b(nolock)
begin
select a.* into #temp1 from SF_MZCFK a(nolock),SF_CFMXK b(nolock)
end
else begin
select a.* into #temp1 from SF_NMZCFK a(nolock),SF_NCFMXK b(nolock)
end
--改為
Insert into #temp1 select a.*
from SF_MZCFK a(nolock),SF_CFMXK b(nolock)
If @@rowcount=0
Begin
Insert into #temp1 select a.*
from SF_NMZCFK a(nolock),SF_NCFMXK b(nolock)
end
性能優化原則12:trig最后的手段
Trig(觸發器)的處理的處理機制是滿足條件時就會在源語句后面加上trig中的代碼進行執行。
它有兩個致命的弊端:(1)不清楚有trig的人會對于執行結果感到迷惑。如常有在插入一張表如果主鍵是indentity的值常取用select @@identity。但如是有trig,tring中有表插入操作,這時的@@identity可能就不是想要的值。(2)trig會束縛選擇。如:有一套單據主表和明細表,當明細表的金額更新時,要同步主表的金額,當程序是一條條更新明細時用trig的作法是每當更新一條明細記錄時都算一處所有明細表的總金額,再去更新主表的金額。這樣有多少條明細就要算多少次,好的作法是不要trig,直接在sql語句中明細更新完明后,一次性算出總金額每條單據的總金額,再更新主表的金額。
對于trig如果有其他手段就一定要避免用trig.性能優化原則13:用戶說好才是真的好
1)有時sql語句性能難以優化,但用戶對于系統響應速度還是不滿意。這時可以從業務分析處理。
如:我們退費模塊錄入發票號原來是用fph like ‘XXX%’。用戶報怨慢,后來改為先用fph=‘XXX’來查,如查不到再fph like ‘XXX%’。這樣在絕大部情況下速度都非常快,同時也滿足小部分情況下模糊查詢的需求。
如:我們的程序要查日表和年表。如果通過日表union表視圖去查會非常慢,性能也難以優化。程序改為普通情況下不查年表,用戶勾上年表標志時才查年表。
(2)查詢統計很多數據時間比較長,就以查詢完一部分數據后可以顯示這部分數據或是用提示,這樣用戶清楚系統在作事情也知道大概進度。這樣情緒上會好很多。
(3)查詢模塊常有一進入時也默認一個查詢,如果性能好,查詢又合用戶心意,這種設計非常好,如果性能不好,那就不是好的設計。用戶對于進入都困難的模塊是沒有好感的。
(4)有戶的耐心與查詢出的記錄成正比。用戶痛恨等待很久卻沒有查詢出記錄。
對于非常慢的查詢,如果有些子查詢非常快可以先作這樣查詢以避免查詢很久卻沒有數據出來的情況。如:按病歷號查在院病人所有費有明細,可以先查一下這個病歷是不是有對應病人。
實戰技巧1:用exists、in代替distinct
Distinct實際上是先收集再刪除這樣兩步都耗資源。
Exists,in會隱式過濾掉重復的記錄
例查自2009年以來有金額大于100的藥品的病人
select distinct a.blh,a.hzxm from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock)where a.patid=b.patid and b.syxh=c.syxh and c.zxrq>'2009' and c.zje>100--改為
select a.blh,a.hzxm from ZY_BRXXK a where exists(select 1 from ZY_BRSYK
b(nolock),ZY_BRFYMXK c(nolock)where a.patid=b.patid and b.syxh=c.syxh and
c.zxrq>'2009'and c.zje>100)
實戰技巧2:縮短union
select …from A,B,C,D,E1
where(E1的條件)
and(其他表聯接條件)
union
select …from A,B,C,D,E2
where(E2的條件)
and(其他表接接條件)
改為
select …from A,B,C,D,(select...from E1where(E1條件)
union
select …from E2where(E2條件))E where(其他條件)
當涉及ABCD表部分耗資源而E1,E2不耗資源時是這樣,如果反過來則改后的性能不一定好。查2009年4月后入院的在院病人在2905病區發生的所有費用明細
select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw
select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw
from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),YK_YPCDMLK d where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.idm=d.idm
union all
select a.hzxm,b.cyrq,d.name,d.xmgg,c.ypsl/c.dwxs ypsl, c.ypdw
from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),YY_SFXXMK d where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.ypdm=d.id and c.idm=0
--改為
select a.hzxm,b.cyrq,d.ypmc,d.ypgg,c.ypsl/c.dwxs ypsl, c.ypdw
from ZY_BRXXK a(nolock),ZY_BRSYK b(nolock),ZY_BRFYMXK c(nolock),(select ypmc,ypgg,ypdm,idm idm from YK_YPCDMLK union select name,xmgg,id,0 from YY_SFXXMK)d
where a.patid=b.patid and b.ryrq>'200904' and b.brzt not in(3,8,9)and b.syxh=c.syxh and c.bqdm='2905' and c.idm=d.idm and c.ypdm=d.ypdm
實戰技巧3:合并sql
把表和where條件類似的兩個或是多個sql合并為一個sql.--查2009年以后的普通、急診、專家掛號人數
declare @ptghs int,@jzghs int,@zjghs int
select @ptghs=0,@jzghs=0,@zjghs=0
select @ptghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=0
select @jzghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=1
select @zjghs=count(*)from GH_GHZDK where ghrq>'2009' and ghlb=2
select @ptghs,@jzghs,@zjghs
--改為
select @ptghs=0,@jzghs=0,@zjghs=0
select @ptghs=sum(case when ghlb=0 then 1 else 0 end),@jzghs=sum(case when ghlb=1 then 1 else 0 end), @zjghs=sum(case when ghlb=2 then 1 else 0 end)
from GH_GHZDK where ghrq>'2009'
select @ptghs,@jzghs,@zjghs
實戰技巧4:去掉游標
把游標當作編程語言的for,do---while的方式,很多情況下都可以去掉,如果光標中間sql語句只有一條一般都是可以去掉光標改為一句sql。
--查當天出院出院日期在2009年4月1到9日間病人的zfdj,zfje置為0
declare @syxh ut_syxh
declare cur1 cursor for select syxh from ZY_BRSYK where cyrq>='20090401' and cyrq<'20090410'
open cur1
fetch cur1 into @syxh
while @@fetch_status=0
begin
fetch cur1 into @syxh
end
close cur1
deallocate cur1
--改為
update ZY_BRFYMXK set zfdj=0,zfje=0
from ZY_BRFYMXK a,ZY_BRSYK b
where a.syxh=b.syxh and b.cyrq>='20090401' and b.cyrq<'20090410'
實戰技巧5:取代count
利用內部函數代替
declare @count int
select * into #tmep1 from ZY_BRFYMXK WHERE zxrq>'200901'
select @count=@@rowcount—可以得到count值
select @count
select @count=count(*)from #tmep1—可以被取代
select @count
利用exists而不count判斷有沒有記錄
declare @count int
Select @count=count(1)from ZY_BRFYMXK WHERE zxrq>'2009‘
If @count>0 … else ….--改為
If exists(Select 1 from ZY_BRFYMXK WHERE zxrq>'2009’)… else ….
第三篇:LoadRunner測試總結
性能測試(并發負載壓力)測試分析-簡要篇
在論壇混了多日,發現越來越多的性能測試工程師基本上都能夠掌握利用測試工具來作負載壓力測試,但多數人對怎樣去分析工具收集到的測試結果感到無從下手,下面我就把個人工作中的體會和收集到的有關資料整理出來,希望能對大家分析測試結果有所幫助。
分析原則:
? 具體問題具體分析(這是由于不同的應用系統,不同的測試目的,不同的性能關注點)? 查找瓶頸時按以下順序,由易到難。
服務器硬件瓶頸-〉網絡瓶頸(對局域網,可以不考慮)-〉服務器操作系統瓶頸(參數配置)-〉中間件瓶頸(參數配置,數據庫,web服務器等)-〉應用瓶頸(SQL語句、數據庫設計、業務邏輯、算法等)注:以上過程并不是每個分析中都需要的,要根據測試目的和要求來確定分析的深度。對一些要求低的,我們分析到應用系統在將來大的負載壓力(并發用戶數、數據量)下,系統的硬件瓶頸在哪兒就夠了。? 分段排除法 很有效
分析的信息來源:
?1 根據場景運行過程中的錯誤提示信息
?2 根據測試結果收集到的監控指標數據
一.錯誤提示分析
分析實例:?Error: Failed to connect to server “10.10.10.30:8080”: [10060] Connection
?Error: timed out Error: Server “10.10.10.30” has shut down the connection prematurely
分析:
?A、應用服務死掉。
(小用戶時:程序上的問題。程序上處理數據庫的問題)
?B、應用服務沒有死
(應用服務參數設置問題)
例:在許多客戶端連接Weblogic應用服務器被拒絕,而在服務器端沒有錯誤顯示,則有可能是Weblogic中的server元素的AcceptBacklog屬性值設得過低。如果連接時收到connection refused消息,說明應提高該值,每次增加25%
?C、數據庫的連接
(1、在應用服務的性能參數可能太小了
2、數據庫啟動的最大連接數(跟硬件的內存有關))
2Error: Page download timeout(120 seconds)has expired
分析:可能是以下原因造成?A、應用服務參數設置太大導致服務器的瓶頸
?B、頁面中圖片太多
?C、在程序處理表的時候檢查字段太大多
二.監控指標數據分析
1.最大并發用戶數:
應用系統在當前環境(硬件環境、網絡環境、軟件環境(參數配置))下能承受的最大并發用戶數。在方案運行中,如果出現了大于3個用戶的業務操作失敗,或出現了服務器shutdown的情況,則說明在當前環境下,系統承受不了當前并發用戶的負載壓力,那么最大并發用戶數就是前一個沒有出現這種現象的并發用戶數。
如果測得的最大并發用戶數到達了性能要求,且各服務器資源情況良好,業務操作響應時間也達到了用戶要求,那么OK。否則,再根據各服務器的資源情況和業務操作響應時間進一步分析原因所在。
2.業務操作響應時間:
? 分析方案運行情況應從平均事務響應時間圖和事務性能摘要圖開始。使用“事務性能摘要”圖,可以確定在方案執行期間響應時間過長的事務。
? 細分事務并分析每個頁面組件的性能。查看過長的事務響應時間是由哪些頁面組件引起的?問題是否與網絡或服務器有關?
? 如果服務器耗時過長,請使用相應的服務器圖確定有問題的服務器度量并查明服務器性能下降的原因。如果網絡耗時過長,請使用“網絡監視器”圖確定導致性能瓶頸的網絡問題
3.服務器資源監控指標:
內存:UNIX資源監控中指標內存頁交換速率(Paging rate),如果該值偶爾走高,表明當時有線程競爭內存。如果持續很高,則內存可能是瓶頸。也可能是內存訪問命中率低。Windows資源監控中,如果ProcessPrivate Bytes計數器和ProcessWorking Set計數器的值在長時間內持續升高,同時MemoryAvailable bytes計數器的值持續降低,則很可能存在內存泄漏。
內存資源成為系統性能的瓶頸的征兆:
很高的換頁率(high pageout rate);
進程進入不活動狀態;
交換區所有磁盤的活動次數可高;
可高的全局系統CPU利用率;
內存不夠出錯(out of memory errors)
處理器:UNIX資源監控(Windows操作系統同理)中指標CPU占用率(CPU utilization),如果該值持續超過95%,表明瓶頸是CPU。可以考慮增加一個處理器或換一個更快的處理器。如果服務器專用于SQL Server,可接受的最大上限是80-85%
合理使用的范圍在60%至70%。Windows資源監控中,如果SystemProcessor Queue Length大于2,而處理器利用率(Processor Time)一直很低,則存在著處理器阻塞。
CPU資源成為系統性能的瓶頸的征兆:
很慢的響應時間(slow response time)
CPU空閑時間為零(zero percent idle CPU)
過高的用戶占用CPU時間(high percent user CPU)
過高的系統占用CPU時間(high percent system CPU)
長時間的有很長的運行進程隊列(large run queue size sustained over time)
磁盤I/O:UNIX資源監控(Windows操作系統同理)中指標磁盤交換率(Disk rate),如果該參數值一直很高,表明I/O有問題。可考慮更換更快的硬盤系統。Windows資源監控中,如果 Disk Time和Avg.Disk Queue Length的值很高,而Page Reads/sec頁面讀取操作速率很低,則可能存在磁盤瓶徑。
I/O資源成為系統性能的瓶頸的征兆 :
過高的磁盤利用率(high disk utilization)
太長的磁盤等待隊列(large disk queue length)
等待磁盤I/O的時間所占的百分率太高(large percentage of time waiting for disk I/O)太高的物理I/O速率:large physical I/O rate(not sufficient in itself)
過低的緩存命中率(low buffer cache hit ratio(not sufficient in itself))
太長的運行進程隊列,但CPU卻空閑(large run queue with idle CPU)
4.數據庫服務器:
SQL Server數據庫:SQLServer資源監控中指標緩存點擊率(Cache Hit Ratio),該值越高越好。如果持續低于80%,應考慮增加內存。如果Full Scans/sec(全表掃描/秒)計數器顯示的值比1或2高,則應分析你的查詢以確定是否確實需要全表掃描,以及SQL查詢是否可以被優化。Number of Deadlocks/sec(死鎖的數量/秒):死鎖對應用程序的可伸縮性非常有害,并且會導致惡劣的用戶體驗。該計數器的值必須為0。Lock Requests/sec(鎖請求/秒),通過優化查詢來減少讀取次數,可以減少該計數器的值。
Oracle數據庫:如果自由內存接近于0而且庫快存或數據字典快存的命中率小于0.90,那么需要增加
SHARED_POOL_SIZE的大小。
快存(共享SQL區)和數據字典快存的命中率:
select(sum(pins-reloads))/sum(pins)from v$librarycache;
select(sum(gets-getmisses))/sum(gets)from v$rowcache;
自由內存:select * from v$sgastat where name=’free memory’;如果數據的緩存命中率小于0.90,那么需要加大DB_BLOCK_BUFFERS參數的值(單位:塊)。緩沖區高速緩存命中率:
select name,value from v$sysstat where name in('db block gets’,'consistent gets','physical reads');
Hit Ratio = 1-(physical reads /(db block gets + consistent gets))如果日志緩沖區申請的值較大,則應加大LOG_BUFFER參數的值。
日志緩沖區的申請情況 :
select name,value from v$sysstat where name = 'redo log space requests';如果內存排序命中率小于0.95,則應加大SORT_AREA_SIZE以避免磁盤排序。
內存排序命中率 :
select round((100*b.value)/decode((a.value+b.value), 0, 1,(a.value+b.value)), 2)from v$sysstat a, v$sysstat b where a.name='sorts(disk)' and b.name='sorts(memory)'
注:上述SQL Server和Oracle數據庫分析,只是一些簡單、基本的分析,特別是Oracle數據庫的分析和優化,是一門專門的技術,進一步的分析可查相關資料。
說明:
以上只是個人的體會和部分資料的整理,并不代表專家之言。算拋磚引玉,有不同看法和更深入的分析的,希望大家勇要發言,以推動我們國內的性能測試工作。
第四篇:LoadRunner性能測試流程及測試標準
loadRunner性能測試 1.什么是性能測試
軟件的功能:對一個軟件基本功能能夠實現,比如:銀行卡能夠正常轉賬成功(用戶數=1)軟件的性能:要求軟件性能更好,一般關注多用戶的使用情況,軟件的響應時間。響應時間例子:登錄一個軟件,點擊“登錄”按鈕時,多久能夠顯示成功登錄的頁面。
性能問題: 1. 每秒平均瀏覽量:2200次/秒
瀏覽量(PV,Page View):即頁面訪問量或點擊量,用戶每次刷新即被計算一次 購票申請:20萬張/秒以上
自身設計瀏覽量100萬次/小時 ?瀏覽量280次/秒
2.響應時間的358原則:
3秒之內,客戶比較滿意 5秒之內,客戶可以接受 8秒之內,客戶可以忍受 大于8秒,無法忍受
3.一般進行性能測試之前,要對系統尤其是數據庫進行備份
負載測試是一種
正常 的測試(在正常測試的指標下測出最大的負載量)
指標或者某種資源達到某種指標,比如響應時間達到多少,比如CPU負載100%等
壓力測試和負載測試二者的區別:
負載測試強調系統在正常工作情況下的性能指標
壓力測試的目的是發現在什么條件下系統的性能變得不可接受,發現應用程序性能下降的拐點
影響系統性能的主要因素
(1)硬件: CPU,內存,硬盤,網卡及其他網絡設備【最好解決】(2)操作系統(3)網絡
(4)中間件(又叫應用服務器),web服務器(5)數據庫服務器(6)客戶端
(7)變成語言,程序實現方式,算法【最難解決】
客戶端=?服務端(Web服務器)=?應用服務器=?數據庫服務器
性能測試主要關心兩個部分:web服務器和應用服務器。客戶端向服務器發送請求
服務器端向客戶端返回應答(響應response)
性能測試的常用術語: 并發(Concurrency):所有用戶在同一時刻(一個時間點,可以精確到毫秒級)做同一件事情或操作,一般針對同一類型的業務
例如:在信用卡審批業務中,一定數目的用戶在同一時刻對已經完成的審批業務進行提交 做并發的測試就稱為“并發測試”。【發測試不包含睡眠時間】 在線(OnLine):多用戶在一段時間內對系統執行操作【包含睡眠時間】
并發測試與在線測試對系統的壓力不同,一般來講并發測試的壓力和在線測試的壓力的比值是10:1。例如:200用戶并發測試相當于2000用戶在線測試。
并發測試一定是多用戶。
請求響應時間
指從客戶端發送一個請求開始計時,到客戶端接到從服務器端返回的響應結果計時結束。在一些工具中,請求響應時間通常被稱為TTLB 即“Time to Last Byte”,意思是從開始發送第一個請求開始,到客戶端收到最后一個字節的響應為止所耗費的時間。請求響應時間的單位一般為“秒”或者“毫秒”
再復雜的響應時間都可以分為3段:請求的響應時間=客戶端的響應時間+網絡的響應時間+服務器的響應時間
一般測試放在內網里,帶寬,網絡不會成為瓶頸。只用分析客戶端的響應問題和服務器的響應問題。一般客戶端的響應很少有問題,一般只分析服務器響應問題即可。
事務響應時間:用戶完成某個具體事務(如跨行取款事務)所需要的時間。事務可能包含多個請求。比如點擊“登錄”按鈕,到登錄進頁面。
事務的響應時間和請求響應時間的區別?
一個事務包含一個或多個請求(一般,一個請求指的是一個http請求)。
點擊率:
每秒鐘用戶向web服務器提交的http請求數。---點擊率越大,對服務器的壓力也越大
---注意:點擊不是指鼠標的一次“單擊”操作。因為在一次“單擊”操作中,客戶端可能向服務器發出多個HTTP請求(比如跳轉頁面需要更新展示圖片等)。
點擊量的計算:假如單擊“登錄”按鈕,請求一個頁面登錄后的歡迎頁面中包含3個圖片,則每個圖片都需要重新發送一個http請求,所以,單擊鼠標一次產生的http請求總數為4=1(登錄請求)+3(圖片請求)點擊率=點擊量/時間
吞吐量:
用戶在任意給定一秒從服務器端獲得的全部數據量,單位是字節 吞吐量/傳輸時間=吞吐率
吞吐率很重要,反應了服務器的處理速度和性能,也是衡量網絡性能的重要指標。TPS(事務數/秒)
在性能測試過程中,要監控服務器系統的各項資源情況,比如:CPU,內存,磁盤及網絡等情況。
吞吐率和點擊率的區別:
吞吐率:指服務器每秒處理的數據量。反應了服務器的處理能力,吞吐率越大,服務器處理能力越強。
點擊率:客戶端每秒向服務器發送請求的數量。反應了服務器的壓力,點擊率越大,服務器的壓力越大
吞吐率受點擊率影響,也受服務器性能的限制。
完美的吞吐率是:在帶寬充足的情況下,吞吐率隨著點擊率的增加而增加。
資源利用率
指對不同的資源系統的使用程度,包括web服務器,操作系統,數據庫服務器,網絡,硬件,是測試和分析瓶頸的主要參數
-如:服務器cpu利用率,磁盤利用率等
它是分析系統性能指標進而改善性能的主要依據,因此是web性能測試工作的重點。
性能測試的策略(即方法):重點測試方法:基準測試,并發測試,綜合場景測試,疲勞強度測試,極限測試,遞增測試
基準測試:一般做的是單用戶測試(Benchmark Testing)
----指測試環境確定以后,對業務模型中涉及的重要業務做單獨的測試。
----目的是獲取單用戶執行時的各項性能指標,為多用戶并發和綜合場景等性能測試分析提供參考依據。
并發測試:就是多用戶的并發測試某個測試點。并發測試對系統要求比較嚴格,因為要模擬一個瞬間壓力。并且要忽略系統的睡眠時間(思考時間)。
遞增測試:
A)指每隔一定時間段(如5秒,10秒)加載不同數目的虛擬用戶執行測試點操作,對測試點進行遞增用戶壓力加載測試。原因:所有用戶(5000)共同登陸可能會導致系統壓力過大,進而影響到后面關心的測試點(buy)的性能,導致關心的測試點結果不準確,所以采取遞增,分散一下前面的壓力,使系統關心的測試點能夠正常的測試。(這里是遞增著登陸)B)測試一個測試點(如:購票),先測試單用戶,再測試20用戶,40用戶等情況,有利于分析,也稱為遞增測試。(這里是遞增著全套測試)
綜合場景測試【重難點】:
通過對系統結構和功能的分析,對用戶的分布和使用頻率的分析,來構造系統綜合場景的測試模型,模擬不同用戶執行不同操作。
如10%的用戶執行瀏覽首頁,50%的用戶執行查詢訂單,40%的用戶執行訂購機票,最大限度地模擬系統的真實場景,使用戶預知系統投入使用后的性能水平。沒特別指明的話,一般都是指在線的。
Login不適合放在綜合場景中運行。
綜合場景:號稱能最真實的模擬實際的生產環境。如測試時間為50分鐘,則綜合場景中的每個腳本都是在循環執行。所以綜合場景中不宜加入login測試點,因為不能真實模擬實際的生產環境。
疲勞強度測試:是一種特殊的強度測試(壓力測試)。指在一定的壓力下(如:相同的用戶數)長時間(疲勞)對系統進行測試,并監控服務器的各項資源情況。如:7x24小時,24小時(如移動電信銀行的服務器)。測試其服務器的穩定性:指長時間的運行過程中,系統的各項資源及時間等指標表現是否正常。
內存泄露:系統的服務器內存都被占用,而沒有釋放。導致系統沒有可用內存。
內存泄露測試:通過LR監控時查看具體的幾項指標,或者通過其它的專門內存泄露檢測工具測試。
數據容量測試:查看系統服務器能否實現大數量下使用情況,系統的各項資源表現情況。如:200G,或者3個T。
極限測試:也叫“摸高測試”,測試系統的極限,如系統最大能承受的用戶數,吞吐量等。
虛擬用戶:Virtual Users 控制臺:Controller 分析工具:Analysis
LoadRunner的三大組件:
虛擬用戶腳本生成器(Virtual User Generator)---Creat/Edit Scripts【Generator:生成器】 壓力調度控制臺(Controller)---Run Load Tests 壓力結果分析器(Analysis)---Analyze Test Results
QTP(功能自動化的工具)和LR(性能測試工具)的區別: QTP關心的是功能方面,LR關心的是性能方面。
QTP關心界面的控件屬性(對象,對象的屬性,屬性值等)等,LR關心的是客戶端和服務器之間往來的數據包。
LR的工作原理:
錄制時,LR記錄客戶端和服務器二者之間的所有對話(數據包),形成腳本,回放時,LR模擬真實的客戶端,向服務器發送請求。并驗證服務器的響應。
LR是怎么記錄下數據包的:(1)基于局域網的廣播原理。【這種用的很少】(2)基于一種嗅探原理sniffer。【目前在用的方式】
虛擬用戶腳本生成器:是用來生成腳本的
LR的常用術語:
虛擬用戶(Virtual User 【簡稱VU】):在場景中,loadRUnner用VU代替實際用戶。Vuser模擬實際用戶執行操作。一個場景可以包含幾十,幾百甚至幾千個Vuser。(每個虛擬用戶是一個進程或者線程,一般用的是線程)
Vuser腳本(Virtual User Script):用于描述VU在場景中執行的操作。(記錄的客戶端發送的請求。)
事物(Transaction):為度量服務器的性能,需要定義事務。事務表示要度量的最終用戶業務流程或操作。
為何要定義事務:因為腳本中將關心的操作(如購票)定義為一個事務,則結果報告中(analysis)就會返回事務的響應時間。不關心的操作就不需要定義成事務。
場景(Scenario):場景是一種文件,用于根據性能要求定義在每一個測試回話運行期間發生的事件。模擬真實環境中,用戶運行的情況。【將腳本放到控制臺去運行(包括設置各種參數)】
綜合場景:將不同的腳本,至少3個放到控制臺去共同運行一段時間。具體定義見PPT。
測試注意:
----設置IE(清楚瀏覽器緩存):進入工具?Internet選項?常規?設置?每次訪問此頁面時檢查
----LR中修改參數:進入Controller?Run?Time Setting?Tnternet Protocol ?Proxy,選擇No Proxy。
Jojo /bean
LR基本測試流程:
制定性能測試計劃(部分)?創建測試腳本?編譯,運行測試腳本【VUG】?創建場景?運行,監控場景,收集數據【Con 控制臺】?生成測試報告,分析測試結果【analysis】
最好用英文命名
小技巧: 彈出結果
日志文件
Transaction 事務
將一個操作設置成事務的目的:獲取操作的響應時間(在analysis報告里)
在帶寬充足的情況下,完美的吞吐率應該隨著點擊率的升高而升高。反過來,當服務器壓力過大服務器處理能力不足時,吞吐率會隨著點擊率的增高而保持恒定或者降低,那么點擊率也會受到相應影響而變慢。
即吞吐率和點擊率是相互影響的。
腳本生成器可以模擬1個用戶,多用戶一定要用控制臺來實現。(控制臺就是來生成管理多用戶的。)
基準測試是單用戶測試,可用腳本生成器(生成的調試結果是沒有響應時間的),但是也還是需要控制臺。因為結果要寫到報告里。(結果生成器analysis得出單用戶測試的結果,比如響應時間等等)
疲勞測試和綜合場景測試的區別就是時間的長短,疲勞測試運行的時間會長一些。
只要業務邏輯不變(操作不變),則不需要重新調試腳本,回歸測試中可以直接利用原來腳本。
調試腳本時請頻繁保存副本,因為LR回退鍵效果不是很好。
腳本必須現在腳本生成器進行運行,執行通過?將腳本放入控制臺,在控制臺執行完畢后?生成結果報告
總的吞吐率
服務水平等級協議
報告中事務響應時間的標準方差值:越趨近于0,說明系統越穩定(每一項事務的響應時間非常相似)
90percent:表示90%的事務都可以在該響應時間內完成。代表一個大多數情況。
HTTP狀態碼: 200表示成功
4XX表示客戶端的失敗 5XX表示服務器的失敗
當場景設定的duration時間結束時,所有的虛擬用戶需要運行完當前的transaction以及action再結束。
基準測試執行方法
單用戶執行腳本操作1分鐘 單用戶執行腳本操作5次
B/S腳本必須要有登陸,有退出(否則假退出其實鏈接還沒斷開,會影響測試結果)
Replay log:腳本執行日志 Recording log:錄制時的日志
Generation log:所有客戶端和服務器二者之間的對話
快捷鍵:
ctrl+G
Go to Line 跳到某一行
跳到對應的日志
基準測試:單用戶測試。3.4 1.7 1.8 1.6 為了規避第一次測試的不準確性,則有兩種測試方法:(1)設置循環5次(N次)
Run-time Setting 循環5次,或者持續運行1分鐘。(取平均值)Run logic:循環次數----設置為5 Pacing:兩次循環之間的步長值(時間間隔)----隨機值2-4秒 Think time:ignore(忽略思考時間),因為對結果沒什么影響
Pacing:步長值,為了更真實的模擬環境(斷開連接,釋放資源),一般選隨機值
基準測試單用戶對服務器壓力不大,一般可以ignore think time。
監控資源:監控服務器的資源
客戶端的資源:自己隨時把握一下,不要成為測試的瓶頸即可。
(2)持續運行1分鐘
當duration和run_time setting中循環(run logic)都有值的話,duration的優先級比較高【二者循環的位置都為action】 Run logic:循環次數----設置為1
Pacing:步長值,為了更真實的模擬環境(斷開連接,釋放資源),一般選隨機值 基準測試單用戶對服務器壓力不大,一般可以ignore think time。監控資源:監控服務器的資源
客戶端的資源:自己隨時把握一下,不要成為測試的瓶頸即可。
并發測試執行方法: 腳本添加集合點
在控制臺設置并發策略
注意:refresh中有兩個選擇,看情況使用。
腳本和控制臺的run-time setting都設置的話,哪個優先級高??控制臺的優先級高!腳本中的run-time setting 何時使用??運行腳本的時候使用
并發測試有兩個步驟:
1)腳本中加并發點(即集合點)
2)在控制臺設置:5個虛擬用戶(VU),可以設置遞增(不設也可),設置并發策略。
Run-time Setting---忽略休息時間,因為需要瞬間壓力。
第五篇:sql語句
簡單基本的sql語句 幾個簡單的基本的sql語句
選擇:select * from table1 where范圍
插入:insert into table1(field1,field2)values(value1,value2)
刪除:delete from table1 where范圍
更新:update table1 set field1=value1 where范圍
查找:select * from table1 where field1 like ’%value1%’
(1)數據記錄篩選:
sql=“select * from 數據表 where 字段名=字段值 order by 字段名 [desc]”
sql=“select * from 數據表 where 字段名 like '%字段值%' order by 字段名 [desc]”sql=“select top 10 * from 數據表 where 字段名=字段值 order by 字段名 [desc]”sql=“select top 10 * from 數據表 order by 字段名 [desc]”
sql=“select * from 數據表 where 字段名 in('值1','值2','值3')”
sql=“select * from 數據表 where 字段名 between 值1 and 值2”
(2)更新數據記錄:
sql=“update 數據表 set 字段名=字段值 where 條件表達式”
sql=“update 數據表 set 字段1=值1,字段2=值2 …… 字段n=值n where 條件表達式”
(3)添加數據記錄:
sql=“insert into 數據表(字段1,字段2,字段3 …)values(值1,值2,值3 …)”
sql=“insert into 目標數據表 select * from 源數據表”(把源數據表的記錄添加到目標數據表)
(4)數據記錄統計函數:
AVG(字段名)得出一個表格欄平均值
COUNT(*;字段名)對數據行數的統計或對某一欄有值的數據行數統計MAX(字段名)取得一個表格欄最大的值
MIN(字段名)取得一個表格欄最小的值
SUM(字段名)把數據欄的值相加
引用以上函數的方法:
sql=“select sum(字段名)as 別名 from 數據表 where 條件表達式”
set rs=conn.excute(sql)
用 rs(“別名”)獲取統計的值,其它函數運用同上。
查詢去除重復值:select distinct * from table1between的用法
between限制查詢數據范圍時包括了邊界值,not between不包括
select * from table1 where time between time1 and time2
select a,b,c, from table1 where a not between 數值1 and 數值2
in 的使用方法
select * from table1 where a [not] in(‘值1’,’值2’,’值4’,’值6’)