1、问题表现:模块列表页面查询接口返回大概6.7~9秒不等;用户投诉严重;
2、背景:系统采用java编写,springMVC+ibatis;
3、问题定位:主要是有sql查询未用索引,代码未分页,同时有频繁的全量查询引起;
a、分析数据量级:涉及5个标,大表约八千多条数据,小表数据量级较少。
b、分析sql:采用多联表查询,联表查询5次,表没有设置索引,sql语句没有使用索引;没有进行分页查询;
开启慢速sql统计,结合日志,将语句和参数直接在sql运行。结合explain工具,观察查询速度和分析结果;
c、分析业务代码;有一个外部接口采用全量查询。每次都会造成服务器mysql的CPU涨到100%;
4、解决过程:
a、sql语句尽量改为小表驱动大表,该方案需要改动代码。不采用
b、相关的表添加索引,修改查询语句,同时结合explain工具逐步使每个联表都采用索引查询;
c、修改代码 采用分页查询;
5、最终结果:
由原来的6~9s不等的查询速度,修改后查询速度为0.36s左右,最大不超过0.6s;
5、相关优化手段;
- 优化mysql的配置;
- 设置mysql开启慢查询记录
- set global slow_query_log=on; //慢查询日志开启
- set global long_query_time=2; //超过2s为慢查询
- set global log_queries_not_using_indexes = ON; //记录不适用索引的查询
- show global status like '%slow%'; //查看慢查询的记录数
- show variables like '%long%';//查看long_query_time值
- show variables like 'log_queries_not_using_indexes'; //查看log_queries_not_using_indexes状态
- 开启之后页面访问触发查询后会默认写入 mysqld-slow.log进行慢sql记录,
- mysqldumpslow -s c -t 20 mysqld-slow.log ; 使用mysqldumpslow找出访问次数最多的 20 个 sql 语句和返回记录集最多的 20 个 sql
- 通过explain记录查询分析上一步骤中的sql耗时 explain + sql语句