首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次查询导出的优化

一次查询导出的优化

作者头像
易兒善
发布2020-05-26 22:12:10
5920
发布2020-05-26 22:12:10
举报
文章被收录于专栏:挖坑填坑挖坑填坑挖坑填坑

先看效果

为了查看慢的地方,添加了一些日志记录。其中遍历1w次便会输出一次时间。

优化前

优化后

优化后

背景

  • 报表的查询导出功能,查询导出使用同一方法获取数据。
  • 页面分页查询耗时还能接收,小数据量导出也能接受。
  • 但是导出数据达到10w级别变得没法接受了。
  • 查看服务器cup使用率一直非常高(双核服务器,cup使用率一直高于50%)。

初步分析

服务器cpu使用高,很可能是数据已经获取到,计算机一直处于快速计算中。从前面日志也证实了这点。

代码分析

``

          result.ForEach(item =>
                 {
                // 省略一部分,简单的判断和赋值
                var trackingList = wobTrackingList.Where(m => m.WOBShipOrderID == item.OrderId);
    if (trackingList.IsStrictSafed())
                {
                    item.ParentTrackingNo = trackingList.FirstOrDefault(m => m.IsParentTrackingNo)?.TrackingNo;
                    var trackNos= trackingList.Where(m => !m.IsParentTrackingNo).Select(m=>m.TrackingNo);
                    item.TrackingNo = string.Join(",", trackNos);
                }
              // 省略一部分,简单的判断和字典中取值。

            // 省略一部分,字符序列化成对象然后取值赋值。前面优化后,进行测试,证明这里也不影响处理速度。
            });

``

其中 wobTrackingList也是提前查询出来的。看似都在内存中计算,应该会很快的。但是忽略了两点。1、Where 运算实际上是查询运算,虽然别人给我们封装好了,单次调用速度很快,但是也比赋值加减运算要慢。2、wobTrackingList中的数据量很可能比外层遍历的数据还要大。wobTrackingList数量越大,Where耗时越多。加之外圈遍历次数多了,累计耗时就上去了。

优化方案

将wobTrackingList 转化成字典。循环中只做取值赋值操作。

                var trackingDic = new Dictionary<Guid, (string parentTrackingNo, string trackNos)>();
                wobTrackingList.GroupBy(m => m.WOBShipOrderID).ToList().ForEach(t => {
                    var parentTrackingNo = t.FirstOrDefault(m => m.IsParentTrackingNo)?.TrackingNo;
                    var trackNos = string.Join(",", t.Where(m => !m.IsParentTrackingNo).Select(m => m.TrackingNo));
                    trackingDic.Add(t.Key, (parentTrackingNo, trackNos));
                });

              result.ForEach(item =>
                     {
                        if (trackingDic.ContainsKey(item.OrderId))
                        {
                            var (parentTrackingNo, trackNos) = trackingDic[item.OrderId];
                            item.ParentTrackingNo = parentTrackingNo;
                            item.TrackingNo = trackNos;
                        }
                });

思考

  • 出现效率问题的地方,多数都和循环处理数据有关。
  • 尽量减少循环中的复杂逻辑,只做简单的取值赋值,判断和计算。
  • 循环中处理数据,特别是耗时严重的操作(如查询数据库),要考虑好循环可能出现的次数。
  • 循环中内存取值,用字典要比list效率高。
  • 面对可能出现1w次循环的地方一定要多思考,多检查代码。
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 先看效果
  • 背景
  • 初步分析
  • 代码分析
  • 优化方案
  • 思考
相关产品与服务
腾讯云代码分析
腾讯云代码分析(内部代号CodeDog)是集众多代码分析工具的云原生、分布式、高性能的代码综合分析跟踪管理平台,其主要功能是持续跟踪分析代码,观测项目代码质量,支撑团队传承代码文化。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档