[经验]一次多表关联性能优化

  • 缘起
  • 尝试
  • 添加索引
  • 添加视图
  • 添加search表
  • 进一步优化
  • 其他问题
  • 思考


缘起

项目初期表拆分的太细,技术负责要求手写sql,mapper.xml中存在很多LEFT JOIN,数据量不是很多的情况下,
发生了一个查询要将近40s的情况,项目本身是汽车相关的项目,会关联到集装箱、客户、订单、车钥匙、各类
服务号等条件,条件本身也很复杂,客户要求多个LIKE查询,单号都无法进行分词


尝试



添加索引

在各个关联字段添加进索引,在数据库中裸跑sql,执行时长从36s降低到7s左右,效果并不是很理想,sql已经
基本上没有办法优化,能提前的条件都提前了



添加视图

众所周知,这个方法并不能实际提升性能



添加search表

这个方法比较理想,在对车辆以及车辆相关条件修改后,定点搜索出该车的数据,然后更新到这张表里,这张表里
包含所有需要的查询条件和查询结果。单表查询速度裸跑sql时长0.021s。
关于这一点我稍微讲一下
比如car表
会包含车架号、服务号、箱号、订单号、是否验车等二十几个字段
会关联客户表和客户目标表
customer_target
target_type, -> ‘CAR’
target_id -> car_id

进行这样的关联,为什么这么关联,因为集装箱也有客户,有的时候集装箱和车需要一期查询,在建表的时候就这么
设计了,包括提单号,是属于客户的,有的时候需要根据这几个条件去查询车和箱的集合。可能有人要吐槽为什么要
一起查询,这也是没有办法的,客户线下的业务已经十几年了,很稳定都是如此,之前用的excel…

做查询表就是把这些字段放在一张整表里,其实数据量不会很多,目前也没有做es、mongo之类的优化,这个表的增长
速度来说,一年可能也才两万条,所以字段太多也没有很大关系,目前来看(大概50多个字段,还能接受)
整表后可能一个search_car_view表中就包含了上述表的很多字段了(本来应该用es来做这件事,工期受限,也没有人熟悉)


进一步优化

1,. 进行常规的操作,比如添加索引,搜索表用myisam
2. 解耦,更新操作用mq去推


其他问题

关于用mq推的问题,延迟基本上可以忽略不计,可以控制在1s之内,属于可以忍受的范围,主要是系统本身属于saas
系统,使用tenet_id区分租户数据,做的时候我写的sql拦截从登录用户里自动注入当前用户租户id,推mq后这个租户id
就丢失了
关于这一点,只有把tenet_id一并发送过去,并且在tenetService中添加setNextTenetId去动态修改下一条sql的拦截


思考

接下来会做分布式的项目,所以会考虑搜索服务抽离。还有一点,我觉得用example还是很不错的,虽然不能限制字段,
但保证了都是单表查询,在普通项目的场景下足够使用了。有的时候宁愿多进行几次单表查询也要尽量避免JOIN查询。
索引该加还是得加,能提升不少性能。
缓存对条件查询帮助很少,我们的项目大多数是偏向b端的erp,关联的东西很多,缓存在这种场景下很难用的上
缓存有用的地方我们这次主要是字典表之类
总体上,这个项目还是收获了不少东西