工作中使用Jmeter或者Loadrunner压测,习以为常,尤其是JMeter,这几年用的很多。性能测试的标准流程:性能需求分析->性能测试方案设计->调试脚本优化脚本->执行测试并收集性能指标->编写性能测试报告等。但是往往我们忽视了性能的调优,在压测的过程中,发现性能问题如何分析如何解决,对于大多数人来说是个盲点。
本文详细介绍性能测试发现的问题以及逐步调优的过程,供参考。
构造“案发”现场
1. 使用存储过程构造200w条用户数据
create procedure create_200wUser()
begin
declare i int;
set i=1;
while i<=200000 do
insert into s_user(username,pwd) values(concat('test',i),md5('123456'));
set i=i+1;
end while;
end
构造数据.png
2. 使用Jmeter 调试登录接口
2.1 使用test1到test10,10个账号调试登录接口,观察聚合报告响应时间
响应时间.png
2.2 使用test999990到test1000000,10个账号调试登录接口,观察聚合报告响应时间
响应时间.png
2.3 使用1999991到2000000,10个账号调试登录接口,观察聚合报告响应时间
小结:从开始的10个账号响应时间非常短,到中段的100w账号,响应时间接近3秒,再到末尾的200w账号接近6秒,甚至超过了我们的经验阀值。那为什么会造成这样的现象呢?感觉像是这个账号查询从第一行傻瓜式的找到最后一行,根本不是我们理解的键值或者索引快速查询的概念。
问题排查
1.验证MySQL是否开启慢查询
image.pngslow_query_log是OFF表示慢查询是关闭的。
2.修改MySQL配置文件,开启并设置慢查询
Windows的MySQL的配置文件是my.ini,慢查询相关配置参考下图:
MySQL慢查询参数配置.png
慢查询配置.png
配置的所有变量均可在命令行模式验证,这里不一一截图。
验证配置变量.png
3.验证慢查询是否生效
再次执行2.3场景,发现慢查询日志已经被记录
发现查询出test2000000竟然花了7.15秒。
4.把出现问题的SQL语句单独执行验证
SQL.png查询花4.182秒,这里考虑到之前是压测,导致时间更长,这里剔除此因素。
验证结论
1.推测原因
之前的分析,很明显,账号是从第一行查询到最后一行,才导致查询效率低,考虑到没有索引的因素。
image.png
s_user表,username和mobile是有索引的,但email和is_delete_time是没有索引的
2.再次跑压测,验证加索引后效果
对email和is_delete_time加索引,再验证SQL查询效率
image.png image.png
加索引后,查询时间为0.023秒。快了不止一个数量级。
加索引后.png
怎么样,效果明显吧。加了索引后,由原来的6秒左右缩短到60多毫秒。现在这只是200w的数据,如果是300w,500w,甚至上亿,可想而已。
网友评论