System.Web.Providers.DefaultMembershipProvider有性能问题/死锁



我们已经开始使用NuGet的microsoft . asp.net . providers . core包中提供的更新后的System.Web.Providers。我们开始迁移现有用户,发现性能变慢,然后出现死锁。这是在不到3万用户的情况下(远低于我们需要创建的100多万用户)。当我们调用提供程序时,它来自每个服务器上的多个线程,并且有多个服务器运行相同的进程。这是为了能够尽快创建我们需要的所有用户,并模拟我们期望在上线时看到的负载。

SQL Server为死锁生成的日志包含以下EF生成的SQL:

SELECT
    [Limit1].[UserId] AS [UserId]
  , [Limit1].[ApplicationId] AS [ApplicationId]
  , [Limit1].[UserName] AS [UserName]
  , [Limit1].[IsAnonymous] AS [IsAnonymous]
  , [Limit1].[LastActivityDate] AS [LastActivityDate]
FROM
    (SELECT TOP (1)
        [Extent1].[UserId] AS [UserId]
      , [Extent1].[ApplicationId] AS [ApplicationId]
      , [Extent1].[UserName] AS [UserName]
      , [Extent1].[IsAnonymous] AS [IsAnonymous]
      , [Extent1].[LastActivityDate] AS [LastActivityDate]
     FROM
        [dbo].[Users] AS [Extent1]
        INNER JOIN [dbo].[Applications] AS [Extent2] ON [Extent1].[ApplicationId] = [Extent2].[ApplicationId]
     WHERE
        ((LOWER([Extent2].[ApplicationName])) = (LOWER(@p__linq__0)))
        AND ((LOWER([Extent1].[UserName])) = (LOWER(@p__linq__1)))
    ) AS [Limit1]

我们手动运行查询,执行计划说它正在执行表扫描,即使有一个底层索引。原因是LOWER([Extent1].[UserName])的使用。

我们查看了提供者代码,看看我们是否做错了什么,或者是否有办法拦截或替换数据库访问代码。我们没有看到任何这样做的选项,但我们确实找到了LOWER问题的根源,.ToLower()在列和参数上都被调用。

return (from u in ctx.Users
    join a in ctx.Applications on u.ApplicationId equals a.ApplicationId into a
    where (a.ApplicationName.ToLower() == applicationName.ToLower()) && (u.UserName.ToLower() == userName.ToLower())
    select u).FirstOrDefault<User>();

有没有人知道我们改变提供者的行为,不使用。tolower(),从而允许使用索引的方法?

您可以在索引列

上为每个Sql Server: lower函数创建一个索引
ALTER TABLE dbo.users ADD LowerFieldName AS LOWER(username) PERSISTED
CREATE NONCLUSTERED INDEX IX_users_LowerFieldName_  ON dbo.users(LowerFieldName)

我也在使用System.Web.Providers.DefaultMembershipProvider成员提供者,但发现它很慢。我改为System.Web.Security.SqlMembershipProvider,发现它要快得多(>快5倍)。

本教程向您展示如何设置SQL数据库,您需要使用SqlMembershipProvider http://weblogs.asp.net/sukumarraju/archive/2009/10/02/installing-asp-net-membership-services-database-in-sql-server-expreess.aspx

这个数据库是自动生成的,使用存储过程,这可能是一个问题,也可能不是你的DB家伙。

最新更新