我写的统计查询速度正常吗?

问题描述 投票:0回答:1

我想知道我为统计编写的这个查询是否很快。目前,使用我在下面编写的数据和查询,它可以在 3 秒内运行。

现在我有一个用户表。角色为 Hr 的人可以创建空缺职位。所以用户有一个空缺列表。角色为候选人的用户可以申请这些职位空缺,并且该职位空缺存储在应用程序表中。所以有一个空缺的申请列表。现在我需要这样的统计数据:

  • HR 用户姓名
  • HR用户共享空缺总数
  • HR用户已完成职位空缺总数
  • HR 用户职位空缺中已达到“简历已批准”状态的申请数量
  • HR用户空缺职位中达到“面试”状态的申请数量
  • HR用户职位空缺中达到“考试”状态的申请数量
  • 并且比该类型的申请状态多+10

我的数据库中的行号:

  • 所有用户:+125 000(55 小时用户)
  • 职位空缺:1900 -申请:+340 000

我的查询如下:

var statisticsQuery = _context.Users
    .OrderBy(hrUser => hrUser.Id)
    .Where(hrUser => hrUser.Roles.Any(p => p.RoleId == "Hr"))
    .Select(hrUser => new VacancyByRecruiterModelDto
    {
        RecruiterId = hrUser.Id,
        RecruiterFullName = hrUser.Name + " " + hrUser.Surname,
        PublishedTotalVacancyCount = hrUser.Vacancies.Count(vac => vac.StatusId == 1),
        CompletedTotalVacancyCount = hrUser.Vacancies.Count(vac => vac.StatusId == 2),
        CvCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 1),
        ExamCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 2),
        InterviewCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 3),
        DocumentCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 4),
        HiringSuccessCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 5),
        CvFailedCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 6),
        CandidateFailedCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 7),
        DontSeeCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 8),
        ReserveCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 9),
        InternCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 10),
        SecurityCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 11),
        DontExamCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 12),
        DontInterviewCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 13),
        HiringStoppedCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 14),
        FailInternshipCount = hrUser.Vacancies
            .SelectMany(vac => vac.Applications)
            .Count(app => app.StatusId == 15),
    }).AsNoTracking();

if (loadMore?.Skip != null && loadMore?.Take != null)
{
    statisticsQuery = statisticsQuery.Skip(loadMore.Skip.Value).Take(loadMore.Take.Value);
}

现在,当我设置 Take 10 并仅查询 10 小时用户时,上述代码在 3 秒内运行。这是正常现象还是应该进一步优化?如果应该做的话,怎么做?

mysql linq asp.net-core asp.net-web-api entity-framework-core
1个回答
0
投票

您可以考虑更新 DTO,将应用程序计数存储为由 EF/Linq 填充的分组,然后公开特定计数的帮助器属性:

public class VacancyByRecruiterModelDto
{
    public int RecruiterId { get; set; }
    public string RecruiterFullName { get; set;}
    public int PublishedTotalVacancyCount { get; set; }
    public int CompletedTotalVacancyCount { get; set; }

    public Dictionary<int, int> ApplicationCounts { get; set; } = new();

    public int CvCount 
    {
        int count = 0;
        ApplicationCounts.TryGetValue(1, out count);
        return count;
        // You could use ApplicationCounts[1], however if no item in the user
        // has a status of 1 there would be no element /w count.
    }
    public int ExamCount 
    {
        int count = 0;
        ApplicationCounts.TryGetValue(2, out count);
        return count;
    }

    // ... repeat for each count...
}

然后填充时:

var statisticsQuery = _context.Users
    .OrderBy(hrUser => hrUser.Id)
    .Where(hrUser => hrUser.Roles.Any(p => p.RoleId == "Hr"))
    .Select(hrUser => new VacancyByRecruiterModelDto
    {
        RecruiterId = hrUser.Id,
        RecruiterFullName = hrUser.Name + " " + hrUser.Surname,
        PublishedTotalVacancyCount = hrUser.Vacancies.Count(vac => vac.StatusId == 1),
        CompletedTotalVacancyCount = hrUser.Vacancies.Count(vac => vac.StatusId == 2),
        ApplicationCounts = hrUser.Vacancies
            .SelectMany(v => v.Applications)
            .GroupBy(a => a.StatusId)
            .ToDictionary(g => g.Key, g.Count())
    });

if (loadMore?.Skip != null && loadMore?.Take != null)
{
    statisticsQuery = statisticsQuery
        .Skip(loadMore.Skip.Value)
        .Take(loadMore.Take.Value);
}

同样,如果有可能存在两种以上的状态,则可以对空缺计数执行此操作。请注意,仅在加载实体时才需要

AsNoTracking
。投影时不需要/使用。

© www.soinside.com 2019 - 2024. All rights reserved.