在azure sql存储过程中使用Merge的性能问题

时间:2015-05-13 13:55:55

标签: sql sql-server stored-procedures merge azure-sql-database

问题:我们遇到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

0 个答案:

没有答案