数据库性能问题分析
索引问题
现象:
tps很低,响应时间长,数据库服务器CPU很高,接近100%,应用服务器负载比较低
索引:
索引是针对数据库中一列或多列的值进行排序的一种结构,存储了表的关键字段,使用索引可快速访问数据库表中的特定信息
分析
数据库服务器CPU高,一般都是因为SQL执行效率低导致的,可能有三方面原因
1、数据库表缺少必要的索引;
2、索引不生效
3、SQL不够优化
联合索引问题
现象:
tps很低,响应时间长,数据库服务器CPU很高,接近100%,应用服务器负载比较低
联合索引
一个索引同时作用于多个字段
联合索引的最左前缀
联合索引检索数据时,会从最左边开始匹配(忽略sql字段顺序),如果匹配不到,就不实用索引
如User表有联合索引my_index(A字段,B字段,C字段)
SQL语句 | 使用索引 |
---|---|
select * from user where A=1; | 使用索引my_index |
select * from user where B=2; | 不使用索引my_index |
select * from user where C=3; | 不使用索引my_index |
select * from user where A=1 and B=2; | 使用索引my_index |
select * from user where A=1 and C=3; | 使用索引my_index |
select * from user where B=2 and C=3; | 不使用索引my_index |
select * from user where C=3 and A=1; | 使用索引my_index |
select * from user where B=2 and C =3 and A=1; | 使用索引my_index |
连接池数量分析
问题,当并发数量增加,接口响应时间增加,数据库服务器CPU、内存等资源使用率低
通过jvisualvm可监测到应用服务器存在线程等待
通过jvisualvm/jprofiler检查是否存在线程等待/block:(jprofiler的Threads--Thread History)
通过对dump日志分析可以看到有很多 TIME_WAITTING的请求,堆栈中包含大量等待连接池的信息:
at com.alibaba.druid.pool.DruidDataSource.pollLast(DruidDataSource.java:1944)
数据库支持的连接数量
数据库内
show variables like "%connections%" # 最大连接数配置一般在800-1000
show status like "%thread%"
字段定义:
Threads_connected:当前打开的连接的数量
Threads_cached:线程缓存内的线程的数量
Threads_created:创建的线程数
Threads_running:激活的线程数(非睡眠状态)
show status like "%connection%"
Connections:视图连接mysql服务器的次数
数据库服务器
netstat anp | grep 3306 查看连接到数据库服务器的数量
修改应用服务器的最大连接数(一般设置50)
# 连接池初始大小
spring.datasource.initialSize=5
# 连接池最小空闲数量
spring.datasource.minIdle=5
# 连接池最大数量
spring.datasource.maxActive=20
# 配置获取连接等待超时的时间
spring.datasource.maxWait=60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
spring.datasource.timeBetweenEvictionRunsMillis=60000
重新压测,会发现线程等待的时间降低,数据库服务器CPU使用率增加