记一个导出超时的排查过程

我做的系统管理后台有一个页面,可以查询或导出数据。查询条件位于页面最顶部,下面有个「查询」按钮,点击之后根据查询条件向后端发起请求,后端返回一个数据列表,页面将其分页展示。

这个功能再简单不过,但是「查询」旁边的「导出」却没按常理出牌,导出超时。。。

页面查询没毛病,导出却不行,第一反应是不是导出的数据太多,导致查询超时了。看了一下导出 URL(GET 请求),pageSize 是 260,按理说区区 260 条数据,不可能查询超时吧,我把 pageSize 改成与页面查询一样大小,又请求了一遍,发现还是不行,这个就有些诡异了。

登录预发机器,看日志,发现 Feign RPC 调用超时。

找到 remote api 的代码,梳理代码逻辑,在可能耗时的语句前后都加上一行日志,预发发布,重新请求。

真凶找到了,说到底还是代码逻辑问题,首先到某张表中查询出 250 条数据,然后用这 250 条数据的 id list 作为条件去查询另一张表,取到 3000 多条数据,再用一个 for 循环去宽表拿这 3000 多条数据的某个相关信息,查询宽表用的还是 rpc,不超时才怪。

在找到真正原因之前,我还纠结了好久是不是 mybatis 的 PagerHelper 没起作用:为什么我要查询 250 条数据,却读出了 3000 多条。后来找之前维护这块代码的同事了解了下,原来「查询」按钮和「导出」按钮所处理的数据不一样,我看代码时先入为主了,误认为「导出」只是把「查询」到的数据用 Excel 保存下来而已。

好吧,这个也反应出产品设计上的一个问题,既然「查询」和「导出」的处理对象不一样,就应该明确的写明「导出xxx」,而不是只用「导出」二字,很容易让人误以为其处理的数据与「查询」一样。

那么如何解决这个查询宽表的耗时问题呢?

这就要回归的业务问题,首先要搞清楚用户要拿这个数据干什么,迅速电话了一下需求方,拉上产品组了个小群,讨论了一番后发现,其中某个字段根本不重要,导出结果没必要带上它。这样就好搞了,把 rpc 查询宽表的语句删掉,直接在内存中组装数据就 OK 了。

问题虽然解决了,但是还要接续思考:如果业务需求必须要带上那个不必要的字段怎么办呢?

这样问题就变的复杂了,即使 rpc 查询速度很快,随着查询数据量变大,for 循环次数一多,必定会导致超时,因此最根本的方式还是数据聚合,把几张关联关系表的数据组合成一张宽表,直接一个 select 语句搞定。

问题虽然简单,暴露出来的问题不少:

  • 产品设计不要反直觉
  • 写代码一定要考虑到功能是否能支撑大数据量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值