1.案例一
线上有个接口平均耗时12s, 此接口用于返回表单搜索时下拉项,共有6个筛选条件下拉项都是通过这个接口一起返回;
分析接口返回耗时长原因:
- 6个sql查询顺序执行,耗时累加;
- 其中三个sql中where条件中含有 xxx is not null and xxx != '' 例如:select distinct os_version from table where check_date = #{0} and os_version is not null and os_version != ''
- postgre库表数据量1700w 表未添加索引
解决思路:
- 问过数据同学,次表中字段会存在为null的情况,可以重新清洗出来一张不含字段为null的表,用于下拉数据的查询;
- 添加索引,同时sql中删除 xxx is not null and xxx != '' 将这个逻辑放在代码中执行, 同时开启多线程执行sql查询
效果:
按思路二优化:字段check_date添加索引
sql给为 select distinct os_version from table where check_date = #{0}
代码改造:
CompletableFuture.runAsync(() -> mapper.getAllOSVersion(this.getLatestScanDate()).stream().filter(str -> StringUtils.isNotBlank(str)).sorted((o1,o2) -> -o1.compareTo(o2))).collect(Collector.toList())
,commonExecutor)
CompletetableFuture.allOF(osVersions) 按照方法二的思路优化后,接口查询时间为2s, 符合3s内返回要求;
2.案例二 问题描述:最近仪表盘频繁发生线上部分功能页面加载不出来 服务cup打满,导致服务暂时不可用,排查后发现此时sql执行变慢,导致数据库连接不能释放,服务cpu飙升
分析问题原因:
- CK库sql执行慢导致服务cpu打满
- 执行慢的sql一般含有multiSearchFirstPosition()
- 由于sql是在代码中拼接,每个条件都用括号包裹,导致括号层级复杂
解决思路:
1.将multiSearchFirstPosition() 改为 positionCaseInsensitive()
2.对于条件拼接sql后不包含 'or' 不再拼接外部括号
效果:
优化后,sql执行性能提升,问题解决