# 600万数据表未建关键索引导致系统整体缓慢

# 背景

客户系统整体使用缓慢,没有卡顿1分钟以上的,打开协同公文、处理相关数据等,都是10秒~20秒的样子。

# 初步分析过程

通过logs_sy/capability.log日志分析,后端相关操作确实很多在20秒以上,说明性能问题出在OA服务器上面。

如下图,每一行最后那个数字就是请求执行耗时,单位毫秒,以23278MS为例,等于请求在服务器上执行了23.278秒。

1720175859479.png

下一步是分析服务器什么导致了慢,服务器慢有很多种原因:CPU 100%、内存100%、磁盘IO性能低+大量读写操作、请求数据库慢等等。

访问服务器,查看CPU利用率较低,不存高负载情况,排除CPU问题。

系统管理员-系统监控导出的Jvm使用情况,内存占用极少,排除内存问题。

再检查JDBC数据库连接情况,发现晚上6点下班期间,在线用户不高的情况下,还存在十多个连接,略有不正常!

一般在线用户不高(200人以内)的情况下,busy connection活跃连接也就1~5个

1720176576735.png

# 深度分析

排除CPU、内存问题后,下一步就是分析Java程序问题,通过Thread Dump看到底什么代码执行慢:

这种情况,需要两台电脑配合了。

一台电脑,用系统管理员登录 - 系统监控 - 找到底部Thread Dump链接;

另一台电脑,用普通用户登录,复现慢的问题。

当另一台电脑,开始复现慢的问题,从第一秒慢开始,系统管理员立刻点击Thread Dump,然后每隔3秒都点击一次Thread Dump,一直这样,直至那台电脑卡顿结束。

随后提供三份文件:

1、把刚才慢时打开的所有Thread Dump另存为导出来

2、把刚才慢时的logs_sy/capability.log导出来

3、把刚才慢时前后半小时的数据库awr报告导出来

通过日志分析,慢的请求都是卡在数据库上:

1720177921297.png

查看awr报告,发现慢的数据库都卡在数据库磁盘IO上:

1720177973753.png

数据库内存配置足够丰富,给到了57G:

1720178040471.png

查看awr的SQL耗费列表,从各种维护看,占用服务器资源最高的几乎都是三条SQL:

1720178157803.png

导出SQL发现都是查询FILE_MAP表:

select filesecret0_.FM_ID as FM1_317_, ...... from FILE_MAP filesecret0_ where filesecret0_.FILE_ID=:1 and filesecret0_.FILE_TYPE=:2

三条资源耗费最大的SQL均用到了where FILE_ID=?,此时重点怀疑:FILE_MAP表是否存在针对FILE_ID的关键索引。

通过索引检查发现FILE_ID除了主键外,没有索引,同时FILE_MAP表已经有590多万条数据。

# 结论和解决方案

综上,问题结论是程序大量from FILE_MAP where FILE_ID=?SQL未走索引,导致一直从数据库磁盘块中解析数据而缓慢。

解决方案是,针对FILE_MAP表高频的where条件字段FILE_ID增加索引 : CREATE INDEX FILE_MAP_FILEID ON FILE_MAP(FILE_ID);,随后问题解决。

创建人:het
修改人:het