数据库排名位置。性能问题

Database rankings positions. Performance problem

我在检索三个游戏排名时遇到性能问题。下面的代码运行大约 300 毫秒,这对我的经理来说太长了。

        public async Task<PointsDto> UserPoints(int userId, int countryId)
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var userData = await context.UsersProfile
                .AsNoTracking()
                .Select(x => new { x.SeasonPoints, x.RankingPoints, x.Id })
                .FirstOrDefaultAsync(x => x.Id == userId);

            var seasonPlace = await context.UsersProfile
                .Select(x => x.SeasonPoints)
                .Where(x => x > userData.SeasonPoints)
                .CountAsync();

            var regionPlace = await context.Users
              .Include(x => x.UserProfile)
              .Select(x => new { x.UserProfile.RankingPoints, x.CountryId })
              .Where(x => x.CountryId == countryId && x.RankingPoints > userData.RankingPoints)
              .CountAsync();

            var worldPlace = await context.UsersProfile
                .Select(x => x.RankingPoints)
                .Where(x => x > userData.RankingPoints)
                .CountAsync();

            var result = new PointsDto()
            {
                RankingPoints = userData.RankingPoints,
                SeasonPoints = userData.SeasonPoints,
                RegionPlace = regionPlace + 1,
                SeasonPlace = seasonPlace + 1,
                WorldPlace = worldPlace + 1
            };

            stopwatch.Stop();
            Console.WriteLine(stopwatch.ElapsedMilliseconds);

            return result;

        }

我尝试下载所有用户并统计他们。然后就更好用了,但是恐怕到时候有1,000,000用户,至少有1/10会下载这么多数据,内存负担会很重。能把执行时间减半就好了,现在不知道怎么办了。

出于性能原因,我会将其委托给 Sql 服务器 TVF。种类

create function Ranking(@userId int, @countryId int)
returns table
as
return
    with userdata as (
       select SeasonPoints, RankingPoints
       from UsersProfile
       where Id = @userId
    )
    select count(case when x.SeasonPoints > userData.SeasonPoints then x.Id end) seasonPlace,
           count(case when x.CountryId = @countryId and x.RankingPoints > userData.RankingPoints then x.Id end) regionPlace,
           count(case when x.RankingPoints > userData.RankingPoints then x.Id end) worldPlace,
    from UsersProfile x
    join userData on (x.RankingPoints > userData.RankingPoints 
                     or x.SeasonPoints > userData.SeasonPoints);

如果缺少索引,查询优化器会建议适当的索引。