问题:我们遇到sql超时,我们认为这些更新归因于最近更改了数据库模式的数据库更改并实现了一个处理删除和将行插入表中的新proc。此表非常大,大约有450万行(但只有五列,其中三列可以为null),并且使用由两列(UserID,GroupID)组成的主键进行索引。不幸的是,我们的数据库人员不可用,我们有点陷入困境之中。
问题:以下存储过程中是否有任何内容存在性能问题或者做错了?
输入:
用户ID
GroupIDs(唯一标识符列表)
UpdateAdminID(启动存储过程的用户的唯一标识符)
期望:
调用此存储过程时,期望每个groupID的一行将插入到UserGroups
中,而不存在。此外,如果找到具有UserID参数且GroupID不在输入列表中的行,则必须将其删除。
步骤:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[sp_UpdateUserGroups] (
@UserID uniqueidentifier,
@Groups IDs READONLY,
@UpdateAdminID uniqueidentifier = NULL
) AS
BEGIN
DECLARE @EnforceUserGroupHeirarchy bit
DECLARE @ClientID uniqueidentifier
DECLARE @AttributeClientID uniqueidentifier
select @ClientID = clientid from users where userid=@userid
select @AttributeClientID=isnull(ParentClientID, ClientID)from clients where ClientID=@ClientID
select @EnforceUserGroupHeirarchy= value from v_clientpreferences where preferenceid=323 and clientid=@AttributeClientID
DECLARE @NumRows INT
SET @NumRows = 1
CREATE TABLE #AllGroups
(
GroupID uniqueidentifier
)
insert into #AllGroups (GroupID) select id from @Groups
if @EnforceUserGroupHeirarchy = 1
BEGIN
WHILE @NumRows>0
BEGIN
INSERT INTO #AllGroups (GroupID)
(
SELECT groupid from groups where (parentgroupid in (select groupid from #AllGroups)) and groupid not in (select groupid from #AllGroups)
)
SET @NumRows = ROWCOUNT_BIG()
END
END
merge usergroups as T
USING (select @UserID as UserId, g.groupid as GroupId from #AllGroups g) as S
on (T.UserID = S.UserID and T.GroupID = S.GroupID)
WHEN NOT MATCHED BY TARGET
THEN INSERT (UserID, GroupID, DateCreated, UpdateAdminID) VALUES(S.Userid,S.GroupID,GetDate(),@UpdateAdminID)
WHEN NOT MATCHED BY SOURCE and T.UserID =@UserID
THEN DELETE;
END
GO
编辑:索引碎片少于30%。
Edit2:EnforceGroupHirearchy查看一个组,并递归地将所有子项添加到#AllGroups
。