有一段时间没对Top SQL提出优化建议了,周五开发小伙伴说:"有一个存储过程执行了两个多小时还没完成,我只是把原来具体语句修改为动态拼接语句而已,之前十分钟就好了!"
纳尼?!改过语句!我什么都不知情!
存储过程业务不算复杂,统计各游戏、各代理商前一天的推广用户量、房卡购买金额、房卡消耗量、活跃用户量、新增活跃用户量
其中代理商存在层级关系(1级、2级),1级的数据=1级代理本身+其下面的2级代理数据。由于不同的游戏记录在不同的表格,开发小伙伴将各游戏对应的数据表、统计字段保存到一张配置表

/******** 简化代码、库名|表名已做替换 ********/
DECLARE loop_cursor CURSOR FOR
SELECT aui.KindID,aui.KindName,aui.AgentUserID,aui.AgentAccounts,aui.AgentNickName,aui.AgentLevel,aui.HighAccounts,aui.Personal,ais.UserID,ais.NickName
FROM LnkServer.DBname.dbo.AgentUserInfo aui WITH(NOLOCK)
LEFT JOIN LnkServer.DBname.dbo.AccountsInfoSimple ais WITH(NOLOCK)
on aui.HighAccounts = ais.accounts
ORDER BY aui.OperateDate DESC
OPEN loop_cursor
FETCH NEXT FROM loop_cursor INTO @KindID,@KindName,@AgentUserID,@AgentAccounts,@AgentNickName,@AgentLevel,@HighAccounts,@Personal,@HighAgentUserID,@HighAgentNickName
WHILE @@FETCH_STATUS = 0
BEGIN
    declare ...

    SELECT @GroupStatRecord=ISNULL(GroupStatRecord,'SparrowGroupStatRecord')
    ,@CardConsumedField=ISNULL(CardConsumedField,'CostRoomCards') FROM DBname.dbo.SparrowConfigForAll WITH(NOLOCK)
    WHERE KindID=@KindID
        
    --推广用户量
    --房卡购买金额
    
    --房卡消耗量
    DECLARE @sqlVoucherConsumeTotal NVARCHAR(MAX);
    set @sqlVoucherConsumeTotal='select @VoucherConsumeTotal = isnull(sum('+@CardConsumedField+'),0)
    from ' +@GroupStatRecord+' with(nolock)
    where StartDate between @StartTime and @EndTime   And KindID=@KindID AND UserID in (
    SELECT DISTINCT ais.UserID
    FROM LnkServer.DBname.dbo.AccountsInfoSimple ais WITH(NOLOCK)
    INNER JOIN LnkServer.DBname.dbo.AgentBindUser T WITH(NOLOCK) ON ais.UserID = T.UserID
    WHERE (T.CreateDate <= @EndTime) AND
    T.KindID = @KindID
    AND T.AgentAccounts = @AgentAccounts
    )' 
        
    DECLARE @pargamVoucherConsumeTotal NVARCHAR(1000)
    SET @pargamVoucherConsumeTotal = '@VoucherConsumeTotal DECIMAL(18,0) out,@StartTime DATETIME,@EndTime DATETIME,@KindID INT,@AgentAccounts VARCHAR(100) '        
                        
    exec sp_executesql @sqlVoucherConsumeTotal,
    @pargamVoucherConsumeTotal,
    @VoucherConsumeTotal=@VoucherConsumeTotal OUTPUT,
    @StartTime=@StartTime,
    @EndTime=@EndTime,
    @KindID=@KindID,
    @AgentAccounts=@AgentAccounts
    
    --单天、累计活跃用户量
    --单天、累计新增活跃用户量

    IF(@AgentLevel=1)
    BEGIN        
        --重复上面的代码,AgentAccounts条件调整
        --累加1级代理下的2级代理
        
        --推广用户量
        --房卡购买金额
        
        --房卡消耗量
        ---------------------------
        DECLARE @sqlVoucherConsumeTotalTemp NVARCHAR(MAX);
        set @sqlVoucherConsumeTotalTemp='select  @VoucherConsumeTotalTemp =isnull(sum('+@CardConsumedField+'),0)
        from '+@GroupStatRecord+' with(nolock)
        where StartDate between @StartTime and @EndTime   And KindID=@KindID AND UserID in (
        SELECT DISTINCT ais.UserID
        FROM LnkServer.DBname.dbo.AccountsInfoSimple ais WITH(NOLOCK)
        INNER JOIN LnkServer.DBname.dbo.AgentBindUser T WITH(NOLOCK) ON ais.UserID = T.UserID
        WHERE (T.CreateDate <= @EndTime) AND
        T.KindID = @KindID
        AND T.AgentAccounts IN
        (select AgentAccounts from LnkServer.DBname.dbo.AgentUserInfo
        where HighAccounts = @AgentAccounts)
        )' 

        DECLARE @pargamVoucherConsumeTotalTemp NVARCHAR(1000)
        SET @pargamVoucherConsumeTotalTemp = '@VoucherConsumeTotalTemp DECIMAL(18,0) out,@StartTime DATETIME,@EndTime DATETIME,@KindID INT,@AgentAccounts VARCHAR(100)'        
                                
        exec sp_executesql @sqlVoucherConsumeTotalTemp,
        @pargamVoucherConsumeTotalTemp,
        @VoucherConsumeTotalTemp=@VoucherConsumeTotalTemp OUTPUT,            
        @StartTime=@StartTime,
        @EndTime=@EndTime,
        @KindID=@KindID,
        @AgentAccounts=@AgentAccounts
        
        --单天、累计活跃用户量
        --单天、累计新增活跃用户量
        
    END    
    SET @VoucherConsumeTotal = @VoucherConsumeTotal + @VoucherConsumeTotalTemp
    
    insert into AgentSpreadDayStatistics...

    FETCH NEXT FROM loop_cursor INTO @KindID,@KindName,@AgentUserID,@AgentAccounts,@AgentNickName,@AgentLevel,@HighAccounts,@Personal,@HighAgentUserID,@HighAgentNickName
END
CLOSE loop_cursor
DEALLOCATE loop_cursor
View Code

相关文章: