第一篇: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中修改参数:进入ControllerRunTime SettingTnternet 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’)