记一次查询优化

九月份接到一则需求有关广告业务的gap报表需求(gap这里可以理解为公司内部广告曝光/点击监控数据和第三方广告曝光/点击监控数据的差值与公司监控曝光/点击数据的比值) 。
产品文档涉及数据较多 , 均出自不同的数据表,查询数据是来自调用rpc服务获取的基础数据,表报接口拼装统一数据对象对外展示 。服务主要分为三个维度查询,按天查询,按小时查询,按地域查询,由于按小时和按地域查询查询条件都是拿到具体的广告ID查询广告拼装每条广告在不同时间范围内(一天24小时)或在不同地域(大概33个?。┑氖菁扑阏故?nbsp;, 数据量有限查询均为700ms左右,速率还可以 。但是在按日期查询广告数据时,按时间范围 , 默认查询当天的在投的并且匹配到监控公司的广告数据大概有20-30条左右,数据显示量也不大,但是查询耗时达到4秒左右,开始以为是因为我使用内存分页的原因,但是加日志排查耗时 , 内存分页在现有的数据量下耗时基本为0,主要耗时的位置在业务逻辑for循环去封装数据的方法上,很纳闷为什么为在这个方法上,几经周折,提取出来内部调用通过外部批量查询的数据列表生成map数据,中通过map获取对相应的依赖对象进行数据封装,优化上线后,效率有所提升,但每天的数据基本保持在4秒左右查询,(翻看了一下其他页面查询代码,数据量都不?。?但查询在1秒一下,疑惑,为什么其他的查询能在一秒一下查询出来?难道是因为内存分页?可是这个查询耗时打印内存分页并不耗时呀,难道是因为数据来源是通过rpc的调用?还是因为查询的条件没有索引?按条件一个表一个表的排查,都有索引啊,并且条件是可以走索引的 。。。)
思前想后,百思不得其解,晚上回家的路上想到H神,对向H神求解,于是向H神提问,把我的问题和H神讲了一边,H神回复用排查调用耗时 。我问线上的也可以吗?可以的,不要猜,用 可以很清楚的查出服务调用耗时问题 。我回复好的,明天回去就试一下 。
第二天一早来到办公室,立马查找的使用文档,因为我司用的是mac安装方式也挺方便 。起初担心自己的操作会对公司服务造成影响先向同事老师说明情况,因为老师没有用过线上排查耗时的问题,所以提示可以先在联调环境下排查,并告诉我了安装方法 。
1.搭建联调环境
2.登录到联调环境
3.在联调服务器上安装因为我司用的是mac所以我的安装命令使用的是
【记一次查询优化】curl -L https://alibaba.github.io/arthas/install.sh | sh
显示.表明安装成功
3.直接在shell下./as.sh就进入了交互页面
4.trace 命令就可以查询接口耗时 使用是trace 接口的全路径.接口所在的类名 接口名
命令输入后,调用接口查询,就会有接口的查询详情打印在下方,注意要多调用几次,只看一次的查询结果可能会出现某个接口查询突发性的时间过长,误导排查结果 。
查询结果大致如下:(上边为单个接口的耗时 , 下边为for循环接口的耗时,均为平均耗时)
找出耗时点,发现耗时问题在我每天查询的结果是在投广告的指定几十条,但是在投广告的过滤在方法之后,也就是调用封装数据的广告会远远大于指定的广告数量,所以优化方法就很快得出,就是在调用之前提前把广告过滤了 。减少不必要的调用,以此来优化 。
果不其然 , 过滤后速率从原来的4秒提升至1.7秒左右 。
期间遇到的问题点:
1.在trace时遇到No class oris ,
2.根据提示sm 发现方法是加载成功的
3.使用cat/root/logs//.log 命令得到如下的日志too large 的error信息
这里说的是我的方法过大,确实是超过了300行,解决方法是把这个方法提取让这个方法尽量的小 。
下边附上我的参考文档:(还有很多技术博客,就不一一列举了)
最后再次对H神表示感谢,一点点进步就可以满足一整天的成就感,无比的开心