首先查找 ApplicationID.
DECLARE @ApplicationId uniqueidentifier
SELECT @ApplicationId = NULL
SELECT @ApplicationId = ApplicationId FROM aspnet_Applications
WHERE LOWER(@ApplicationName) = LoweredApplicationName
IF (@ApplicationId IS NULL)
RETURN
SELECT @ApplicationId = NULL
SELECT @ApplicationId = ApplicationId FROM aspnet_Applications
WHERE LOWER(@ApplicationName) = LoweredApplicationName
IF (@ApplicationId IS NULL)
RETURN
然后创建一个临时表(应该使用表数据类型)以便存储用户的profiles信息。
-- Create a temp table TO store the select results
CREATE TABLE #PageIndexForUsers
(
IndexId int IDENTITY (0, 1) NOT NULL,
UserId uniqueidentifier
)
-- Insert into our temp table
INSERT INTO #PageIndexForUsers (UserId)
CREATE TABLE #PageIndexForUsers
(
IndexId int IDENTITY (0, 1) NOT NULL,
UserId uniqueidentifier
)
-- Insert into our temp table
INSERT INTO #PageIndexForUsers (UserId)
如果这个调用非常频繁,由于临时表的创建这会变得很高的IO吞吐量。它的运行也会贯穿两个大表――aspnet_Users和aspnet_Profile。采用这种方式编写的存储过程,如果一个用户有多个profiles,那么它会返回用户的所有profiles。但是正常情况下,我们会为每个用户存储一个profile。因此,这里不需要创建临时表。
此外,也不需要做像LIKE LOWER(@UserNameToMatch)这样的操作。我们也总是使用equal操作符来判断两个直接匹配的用户名。
因此,我们打开这个存储过程并做了一些如下调查:
IF @UserNameToMatch IS NOT NULL
BEGIN
SELECT u.UserName, u.IsAnonymous, u.LastActivityDate, p.LastUpdatedDate,
DATALENGTH(p.PropertyNames)
+ DATALENGTH(p.PropertyValuesString) + DATALENGTH(p.PropertyValuesBinary)
FROM dbo.aspnet_Users u
INNER JOIN dbo.aspnet_Profile p ON u.UserId = p.UserId
WHERE u.LoweredUserName = LOWER(@UserNameToMatch)
SELECT @@ROWCOUNT
END
ELSE
BEGIN -- Do the original bad things
BEGIN
SELECT u.UserName, u.IsAnonymous, u.LastActivityDate, p.LastUpdatedDate,
DATALENGTH(p.PropertyNames)
+ DATALENGTH(p.PropertyValuesString) + DATALENGTH(p.PropertyValuesBinary)
FROM dbo.aspnet_Users u
INNER JOIN dbo.aspnet_Profile p ON u.UserId = p.UserId
WHERE u.LoweredUserName = LOWER(@UserNameToMatch)
SELECT @@ROWCOUNT
END
ELSE
BEGIN -- Do the original bad things
在本地运行得很好。现在是该放到服务器上去运行的时候了。该存储过程是ASP.NET 2.0 Profile Provider使用的重要存储过程,也是ASP.NET框架的核心。如果我们在这里做了些错误的处理,虽然我们可能不会立即看到这个问题,但是可能一个月后我们会意识到用户的profile发生了混乱并且没有办法返回了。因此,在没有做好充分测试的情况下,直接将其部署到产品服务器上是一项艰难的决定。但是我们并没有足够的时间来做测试。我们已经关闭了服务器。因此,我们聚集在一起,心理默默祈祷并点击了在SQL Server Management Studio 上的“执行”按钮。
这个存储过程运行得很好。在服务器上我们注意到CPU使用率从100%降低到了30%。IO使用率也下降到了40%。
我们再次活过来了!