美文网首页初见
一次查询导出的优化

一次查询导出的优化

作者: 易兒善 | 来源:发表于2020-05-22 10:39 被阅读0次

先看效果

为了查看慢的地方,添加了一些日志记录。其中遍历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次循环的地方一定要多思考,多检查代码。

相关文章

  • 一次查询导出的优化

    先看效果 为了查看慢的地方,添加了一些日志记录。其中遍历1w次便会输出一次时间。 优化前 ; 优化后 背景 报表的...

  • Mysql导出设计文档

    查询所有的表结构 导出到文档 1、可以手写导出 2、利用工具:如navicate查询结果导出

  • MySQL性能调优

    MYSQL查询语句优化 mysql的性能优化包罗甚广: 索引优化,查询优化,查询缓存,服务器设置优化,操作系统和硬...

  • mysql优化

    MYSQL优化 为查询缓存优化你的查询 EXPLAIN你的SELECT查询。根据结果给出分析相应的查询优化 当只要...

  • MySQL远程带条件导出数据

    MySQL远程带条件导出数据 远程查询结果导出到本地(query.sql为查询语句):

  • Sqlserver数据导出

    sqlsever 查询数据导出 1.验证查询命令是否正确 选择所需数据库,点击新建查询 2.执行导出程序 2.1 ...

  • Day2:MySQL慢查询基础-查询慢原因

    说在前面: 查询优化、索引优化、库表结构优化是查询性能优化的三驾马车。 完成一个完整的查询生命周期,查询需要在...

  • Doris系列19-查询结果集导出

    一. 查询结果导出概述 语法:SELECT INTO OUTFILE 语句可以将查询结果导出到文件中。目前支持通过...

  • 《高性能Mysql》-查询优化

    优化性能需要查询优化、索引优化、库表结构优化这三辆马车齐头并进。这篇文章主要围绕查询优化,要对查询进行优化首先需要...

  • PostgreSQL 源码解读(29)- 查询语句#14(查询优

    本节简单介绍了PG查询逻辑优化中的子查询(subQuery)上拉优化,包括查询优化中子查询的基本概念,同时介绍了主...

网友评论

    本文标题:一次查询导出的优化

    本文链接:https://www.haomeiwen.com/subject/mzbxnhtx.html