即使是小型集合,LINQ查询执行速度也很慢

时间:2017-04-24 13:22:06

标签: c# asp.net asp.net-mvc linq c#-4.0

我有一个非常奇怪的问题,我的LINQ查询执行速度如此之慢。代码如下:

var user = ctx.Users.FirstOrDefault(x => x.Username== username);

ViewBag.Items = user.Items.GroupBy(x => x.ItemId).Select(pr => new SalesViewModel
{
 ImageURL = pr.Select(x=>x.ImageURL).FirstOrDefault(),
 Title= pr.Select(x=>x.Title).FirstOrDefault(),
 Sales = pr.Select(x=>x.Transactions.Sum(y=>y.QuantitySold)).FirstOrDefault()
 })
 .OrderByDescending(x=>x.Sales)
 .ToList();

因此,用户对象包含ICollection集合,其中包含1300个项目。并且这些项目中的每一个都包含另一个ICollection,称为" Transactions"集...

我注意到其中每个最多都有20-25个交易,因此项目内的集合不是那么大......

我在这里做错了什么,为什么LINQ需要30-40秒来处理这段代码?

有没有办法让它变得更好?

3 个答案:

答案 0 :(得分:0)

请将您的linq查询更改为:

var user = ctx.Users.FirstOrDefault(x => x.Username== username);

ViewBag.Items = user.Items.GroupBy(x => x.ItemId).Select(pr => new SalesViewModel
{
    ImageURL = pr.FirstOrDefault(x=>x.ImageURL),
    Title= pr.FirstOrDefault(x=>x.Title),
    Sales = pr.FirstOrDefault(x=>x.Transactions.Sum(y=>y.QuantitySold))
})
.OrderByDescending(x=>x.Sales)
.ToList();

答案 1 :(得分:0)

尝试此方法:

var ids = user.Items
    .GroupBy(x => x.ItemId)
    .Where(x=> x.Any())
    .Select(pr => pr.First().Id); /* No ToList yet */

user
    .Items
    .Where(x=> ids.Contains(x.Id)) // <--
    .Select(pr => new SalesViewModel
    {
        ImageURL = x.ImageURL,
        Title= x.Title,
        Sales = x.Transactions.Sum(y=>y.QuantitySold)
    })
    .ToList();

方法是,从昂贵的GroupBy读取主键并将其用作主查询的子查询。在LINQPad或SSMS中尝试一下,看看这是否有所不同。

答案 2 :(得分:0)

正如Ivan Stoev在评论中写道,它应该是由延迟加载引起的N + 1查询问题。这里的答案是使用include语句并在对事务求和之前加载子实体。

var user = ctx.Users.FirstOrDefault(x => x.Username== username).Include("Items").Include("Transactions");