【问题标题】:View takes too long to render my results查看需要太长时间才能呈现我的结果
【发布时间】:2015-07-29 05:22:42
【问题描述】:

我有一个控制器,它基本上通过 return View(result); 返回一个 IOrderedQueriable 对象;

关键是,当视图尝试执行该查询时,它会花费大量时间,并且最终会出现一些超时异常。我相信原因是因为在结果下创建的查询非常复杂。我想知道是否可以就如何改进我的 linq 查询提供一些建议。

这是我的丑陋和讨厌的查询:

public ActionResult FileList(string productName, string projectName)
{
    var tagCount = (from l in db.FileDatas
        from t in db.ProcessedFiles.Where(x => l.FileId == x.FileId &&
            l.ProductId == x.ProductId &&
            l.ProjectId == x.ProjectId &&
            l.Product.Product1.Equals(productName))
            .GroupBy(t => new { .ProductId, t.ProjectId, t.FileId, l.ExtensionId })

    select new GroupedTagsRow
    {
        ProductName = l.Product.Product1,
        ProjectName = l.Project.Project1,
        FileName = l.File.File1,
        Occurrences = t.Sum(x => x.Occurrences)
    });

    var unprocessedTags = db.UnProcessedTags
        .Where(x => x.Product.Product1.Equals(productName) &&
            x.Project.Project1.Equals(projectName) &&
            x.TagId != 1);

    var listOfFiles = db.FileDatas
        .Where(x => x.Product.Product1.Equals(productName) &&
        x.Project.Project1.Equals(projectName));

    var result = listOfFiles
        .GroupBy(file => file.File)
        .Select(data => new File
        {
            FileName = data.FirstOrDefault().File.File1,
            TotalTags = tagCount.Where(p => p.FileName.Equals(data.FirstOrDefault().File.File1)).Sum(x => x.Occurrences).ToString(),
                UnprocessedTags = unprocessedTags.Where(p => p.File.File1.Equals(data.FirstOrDefault().File.File1)).DefaultIfEmpty().Count().ToString(),
        })
        .OrderBy(fileName => fileName.FileName);

    return View(result);                    
}

上面的代码执行得非常快,我猜这是因为它只是自己生成查询。但是当它进入视图并尝试迭代结果时,它需要很长时间才能到达 foreach 循环。

@model IQueryable<File>

@{
    ViewBag.Title = "File";
}

<h4>Number of files: <strong> @Model.Count() </strong></h4>

@foreach (var item in Model)
{
    @RenderItem(item);
}

知道如何优化它吗?最后,我的查询返回大约 100 个 File 对象。但是对象内每个属性的初始化正在杀死系统......

谢谢!

【问题讨论】:

  • 我可以看到杀死我的查询的操作是从 File 对象填充 TotalTags 和 UnprocessedTags 的两个操作
  • 也许在您的操作方法开始构建结果对象之前尝试执行一些查询。例如tagCount = &lt;query here&gt;.Select(..).ToList()。我认为这需要很多时间,因为每个子查询都是针对listOfFiles中的每个文件执行的
  • 感谢您的回复,您的建议使事情变得更快,但我最终在 SQL 上编写了整个查询并创建了一些视图,然后我在我的 Web 应用程序中引用了这些视图。这使得技巧和执行要快得多! :)

标签: c# asp.net performance linq linq-to-sql


【解决方案1】:

使用 Sql Profiler 查看实际执行的 SQL 命令。我怀疑您可能会看到针对返回的每个结果的多个查询(即,这可能会为您的 100 个结果发出超过 200 个 SQL 命令)。

如果您分别检索 TotalTags 和 UnprocessedTags 然后将它们组合到内存中,您可能会发现它更快。

【讨论】:

  • 感谢您的评论!正如我上面所说,我最终将所有 sql 代码放在适当的 sql 查询中,并创建了一个在控制器中引用的视图。这让事情现在变得更快了。谢谢1
猜你喜欢
  • 2012-12-04
  • 1970-01-01
  • 1970-01-01
  • 2022-12-23
  • 1970-01-01
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
相关资源
最近更新 更多