繁体   English   中英

ef内核中查询的长时间响应

Long time response for query in ef core

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

当按用户和日期分组我们时,我正在为交易创建一个选择,并且我还需要显示累加器。 结果是正确的,但处理此查询的时间为60s。

我正在使用ef core 2.2,并且尝试使用类似的linq表达式,但响应时间相同。

public async Task<ListDataPagination<AdvanceIn, TotalizerAdvanceInDate>> AdvanceInDateAsync(int page, int? limit=15)
        {
            IQueryable<AdvanceIn> query;

            var data = new ListDataPagination<AdvanceIn, TotalizerAdvanceInDate>();

            query = Context.SaleTransaction
                .Include(s => s.AdminSale)
                .ThenInclude(a => a.PlaceCategory)
                .Include(s => s.Transaction)
                .Where(s => s.PayIn.Date <= DateTimeOffset.UtcNow.Date.AddDays(6) 
                    && s.Paid == false
                    && s.ProcessingPaid == false
                    && (s.Transaction.Status == TransactionStatus.Authorized || s.Transaction.Status == TransactionStatus.Paid) )
                .GroupBy(s => new { s.AdminSaleId, s.PayIn.Date })
                .Select(s => new AdvanceIn()
                {
                    Count = s.Count(),
                    NetAmountSum = s.Select(t => t.NetAmount).Sum(),
                    GrossAmountSum = s.Select(t => t.Transaction.GrossAmountWithoutSaleDiscount).Sum(),
                    AdminSale = new SaleTransferReadModel {
                        Id = s.Select(t => t.AdminSale).First().Id,
                        PlaceName = s.Select(t => t.AdminSale).First().PlaceName,
                        PlacePhoto = s.Select(t => t.AdminSale).First().PlacePhoto
                    },
                    PayIn = s.Select(t => t.PayIn).First(),
                    SaleTransactionId = String.Join(",", s.Select(x => x.Id.ToString()))
                })
                .OrderBy(s => s.PayIn);

            var list = await query.AsNoTracking().ToListAsync();
            data.Totalizer = new  TotalizerAdvanceInDate {
                Count = list.Sum(t => t.Count),
                NetAmountSum = list.Sum(a => a.NetAmountSum),
                GrossAmountSum = list.Sum(a => a.GrossAmountSum)
            };

            data.Page = page;
            data.TotalItems = list.Count();
            data.TotalPages = data.TotalItems / limit.Value;

            data.Data = query.Skip(limit.Value * page)
                   .Take(limit.Value)
                   .ToList();


            data.PageTotalizer = new TotalizerAdvanceInDate {
                Count = data.Data.Sum(a => a.Count),
                NetAmountSum = data.Data.Sum(a => a.NetAmountSum),
                GrossAmountSum = data.Data.Sum(a => a.GrossAmountSum)
            };

            return data;
        }

我希望减少获取此查询响应的时间。

1 个回复

一些建议:

  1. 正如NetMage指出的那样,您的第一个.ToList()调用是一个主要问题。 这将整个集合具体化到内存中,这意味着将所有这些数据从DbServer拉到Web服务器。 据我所知,这样做只是为了计数。

更新的代码:

query = Context.SaleTransaction
               .Where(s => s.PayIn.Date <= DateTimeOffset.UtcNow.Date.AddDays(6) 
                    && s.Paid == false
                    && s.ProcessingPaid == false
                    && (s.Transaction.Status == TransactionStatus.Authorized || s.Transaction.Status == TransactionStatus.Paid) )
                .GroupBy(s => new { s.AdminSaleId, s.PayIn.Date });
var rowCount = query.Count();

这将执行一个查询以获取组数,而不会撤回所有数据。

  1. 使用投影( Select )时,不需要使用Include语句。 这些仅适用于在检索实际实体图时(例如在更新期间)。

  2. 接下来,一旦您从Count计算了您的分页数字:

--

data.Data = await query.Select(s => new AdvanceIn()
    {
       Count = s.Count(),
       NetAmountSum = s.Select(t => t.NetAmount).Sum(),
       GrossAmountSum = s.Select(t => t.Transaction.GrossAmountWithoutSaleDiscount).Sum(),
       AdminSale =  s.AdminSale.OrderBy(/* ?? */).Select(a => new SaleTransferReadModel 
       {
           Id = a.Id,
           PlaceName = a.PlaceName,
           PlacePhoto = a.PlacePhoto
       }).First(),
       PayIn = s.Select(t => t.PayIn).First(), // Nope! don't return an Entity. Get a value or create a ViewModel like SaleTransferReadModel.
       SaleTransactionId = String.Join(",", s.Select(x => x.Id.ToString())) // This might not work for EF2SQL... Consider returning the list of IDs and projecting to a Display String in the ViewModel.
    }).OrderBy(s => s.PayIn)
    .Skip(limit.Value * page)
    .Take(limit.Value)
    .ToListAsync();

这将运行第二个查询,以仅从数据库中拉回所选数据页面。 我会考虑在此处使用async来允许您的Web服务器在此查询运行时处理请求,这可能需要一秒钟左右的时间,具体取决于所涉及的数据。

此处的主要更改/注意事项:不要重复“ First调用”以填充内部视图模型。 根据第一个所需的子记录,使用Select对其进行投影。 使用First等时,应始终包含OrderBy因为您不能依赖任何默认顺序。

接下来,代码将嵌入实体PayIn。 从PayIn中获取一个字段以将其返回或投影到ViewModel中。 您不希望在视图模型中嵌入任何实体,因为当序列化程序将其转换为JSON或其他格式时,它将触摸PayIn上的任何属性并可能触发延迟加载。

最后是ID列表上的string.Join() 可能行得通,但可能不行,并且EF核心有一个讨厌的习惯,会发出警告,称它会过早地实现查询以使其分两步进行,从而破坏了整个目的。 相反,我会在视图模型中Select ID的List<string> ,然后在执行string.Join()的视图模型上公开一个额外的属性。

public ICollection<Guid> SalesTransactionIds { get; set; } // Populate this in your Linq expression...

public string DisplaySalesTransactionIds 
{
   get { return string.Join(",", SalesTransactionIds); }
}

**注意:如果您对类型感到SalesTransactionIds.Select(x => x.ToString()) ,可以在Join内使用SalesTransactionIds.Select(x => x.ToString())

当序列化程序对其进行爬网时,视图/网格将在视图模型中获得一个名为DisplaySalesTransactionIds的字符串属性,该属性将为您提供以逗号分隔的列表。

尝试一下其中的一些,看看它是否可以加快速度。

1 为什么这个EF查询需要这么长时间?

我们有一个EF4查询,大约需要10秒钟才能完成。 查询并不复杂,但由于包含了大量相关表,因此需要很长时间。 我正在努力加快速度。 原始查询看起来像这样(为了清晰起见缩短了)...... CreateSupportTicketListOverview()是一个获取实体并根据它返回 ...

2 EF 5.0中长时间运行的查询

以下查询应返回大约7200条记录: 生成的sql(从sql server profiler: 从Entity Framework执行时,不会在任何合理的时间内完成,而是从SSMS立即执行。 使用take(200)将行数限制为200,即使从EF调用,查询也会运行约50毫秒。 ...

3 为什么EF查询数据需要这么长时间才能加载到内存中?

我有一段代码可以执行一个很大的查询,有很多联接,等等。为简单起见,这里大概有以下结构: 秒表显示已过去30秒,返回9行和大约30列数据(无文本字段)。 因此,我使用SQL Server Profiler嗅探了该查询,的确是一个庞然大物。 我摆弄和试着优化了一些索引,并在200毫秒内执 ...

4 Excel在长时间的SQL查询中没有响应

我正在寻找有关如何避免Excel在长时间SQL查询期间不响应的建议。 如果我在已有数据的情况下运行我的VBA代码,则执行时间不到一秒钟。 当使用SQL查询运行代码时,执行时间最多跳到11秒,这与在Microsoft SQL Server Management Studio中运行查询所花费 ...

5 MySQL NOT IN查询需要太长时间才能响应

查询需要很长时间才能响应~40分钟。 我也尝试过同时使用NOT EXISTS和LEFT JOIN / IS NULL版本的上述查询。 consumer表有 consumer_id varchar(12) active_flag varchar(6) 频率变 ...

6 查询花费太长时间才能响应

我有项目的PHP列表。 我正在从SQL数据库中获取数组。 一切正常,但最近的记录正在增加,并且突然没有在列表中显示记录。 建议! 我尝试了内部联接,但记录较少,这很好 查询是: ...

2019-09-08 17:22:28 1 47   mysql/ sql
7 EF中首次查询期间的长时间延迟-每次执行新查询时都会发生这种情况吗?

因此,似乎当EF运行其第一个查询时,它必须即时编译该查询。 由于已编译的查询现在位于缓存中,因此对查询的后续调用将更快。 即使我的DBContexts可能来去去去,似乎已编译的查询仍保留在缓存中。 (如果我理解正确) 但是,在第一次运行每个查询时每个查询都会有延迟,或者在第一次运行任 ...

8 长时间查询的Solr查询响应时间慢

我有一个单核[1],不可复制的Solr索引,包含约4000万份文档。 每个文档都有两个字段,一个存储,另一个不存储。 我搜索非存储字段,存储的字段是我的结果。 该索引的响应时间约为8秒。 需要注意的是,我没有进行典型的全文查询。 每个查询包含数十个OR字词。 我希望这会很慢,但不 ...

10 对长时间运行的查询SailsJS的响应为空

我目前正在Raspberry Pi上运行SailsJS,但是一切运行良好,但是当我尝试响应结果时执行sails.models.nameofmodel.count()时,最终得到的响应为空。 我能够在日志中看到找到的号码(73689)。 但是,在响应时,我仍然会得到一个空响应。 我使用 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM