SQL优化案例

130 阅读2分钟

1.案例一

线上有个接口平均耗时12s, 此接口用于返回表单搜索时下拉项,共有6个筛选条件下拉项都是通过这个接口一起返回;

分析接口返回耗时长原因:

  1. 6个sql查询顺序执行,耗时累加;
  2. 其中三个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 != ''
  3. postgre库表数据量1700w 表未添加索引

解决思路:

  1. 问过数据同学,次表中字段会存在为null的情况,可以重新清洗出来一张不含字段为null的表,用于下拉数据的查询;
  2. 添加索引,同时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飙升

分析问题原因:

  1. CK库sql执行慢导致服务cpu打满
  2. 执行慢的sql一般含有multiSearchFirstPosition()
  3. 由于sql是在代码中拼接,每个条件都用括号包裹,导致括号层级复杂

解决思路:
1.将multiSearchFirstPosition() 改为 positionCaseInsensitive() 2.对于条件拼接sql后不包含 'or' 不再拼接外部括号

效果:
优化后,sql执行性能提升,问题解决