为什么我的linq to SQL查询速度很慢?

时间:2016-11-20 17:32:00

标签: c# sql linq

我在生产环境中得到的查询非常慢。我想知道为什么以及是否有更好的方法来实现相同的结果。

public async Task<Membership> FindByEmailByAccessL1OrL3OrL4Async(string email)
{
    return await (from m in this.Queryable()
                  where m.Email == email
                        && (m.RoleMemberships.Select(r => r.RoleId).Contains(RoleConstants.ACCESSGRANTEDL1ID)
                            || m.RoleMemberships.Select(r => r.RoleId).Contains(RoleConstants.ACCESSGRANTEDL3ID)
                            || m.RoleMemberships.Select(r => r.RoleId).Contains(RoleConstants.ACCESSGRANTEDL4ID))
                  select m).SingleOrDefaultAsync();
}

简而言之,此查询的目的是通过电子邮件获取用户成员资格并继续登录。更多我获得了用户会员资格,更多的查询将会很慢。

谢谢,

大卫

修改

this.Queryable()相当于执行select * from MembershipsMembership表有很多角色,角色有很多成员资格。

此外,成员资格表最多需要12秒才能获得240行的登录信息。我必须按角色过滤,因为电子邮件值在系统中不是唯一的。只有一些角色可以访问登录,这些角色将拥有唯一的电子邮件。这就是我必须过滤的原因。此查询返回一个成员资格以继续登录,该成员资格已通过上述查询选择。所以没有IQueryableIEnumerableList,只有SingleOrDefault值。

2 个答案:

答案 0 :(得分:3)

我认为生成的查询非常糟糕,因为你多次做同样的事情是:

m.RoleMemberships.Select(r => r.RoleId)

相反,您可以使用以下方法执行此操作:

public Task<Membership> FindByEmailByAccessL1OrL3OrL4Async(string email)
{
    return (from m in this.Queryable()
            where m.Email == email
              && (m.RoleMemberships.Any(
                    r => r.RoleId == RoleConstants.ACCESSGRANTEDL1ID 
                      || r.RoleID == RoleConstants.ACCESSGRANTEDL3ID 
                      || r.RoleID == RoleConstants.ACCESSGRANTEDL4ID)
            select m).SingleOrDefaultAsync();
}

以上会让事情变得更好我猜。您可以使用调试器在两种情况下检查生成的查询。

另请注意,您无需等待结果,只需返回任务,调用者就需要等待它。

答案 1 :(得分:0)

我认为有很多数据需要加载,EF是非常慢的映射技术,可以创建有趣的查询(你可以看到这个here)。你有性能问题吗?也许你应该选择其他的映射技术(堆叠精巧的例如Dapper)。当我们进行测试时,它比EF快两倍。