程序高 CPU 使用率

Procedure high CPU usage

我们有一个应用程序 运行 特定 SP 的请求率很高。在 SQLServer Profiler 中,我看到这个 SP 的使用率很高 CPU,但是当我 运行 改变 SP 时(改变不改变 SP 逻辑,它只是改变现有的 SP!)cpu 使用去下降,几个小时后再次上升。 我真的很困惑为什么这个动作可以降低 CPU 的使用率,我该如何解决?

SP的定义如下:

ALTER PROCEDURE [dbo].[MySP]
    @UId BigInt ,
    @Ml int, 
    @MXL int, 
    @R1 int, 
    @R2 int,
    @R3 int,
    @R4 int ,
    @debugmode bit
AS 
    If(@Ml < 1)
        Set @Ml = 1

    If (@MXL > 99 )
        Set @MXL = 99

    If (@Ml >= 42 OR @debugmode = 1)
    Begin
        with 
        tmp_one as
        (
            SELECT
                    R.Id as RID 
                    FROM    [U] as U
                                Inner Join
                            [R] as R
                                On  R.UId = U.Id

                    WHERE       ([R].[L] BETWEEN @Ml AND @MXL) 
                            AND (R.UId <> @UId) 
                            AND (0 =  [U].[Status])
                            AND (1 =  [U].[ActionStatus])
                            AND ((ABS((BINARY_CHECKSUM(NEWID(),R.Id)))% 10000)/100 ) BETWEEN @R1 AND (@R1 + 10)
        )
        Select  top 10 RID
            From    tmp_one
            Order By RID
    End

    Else 
    Begin
        with 
        tmp_one as
        (
            SELECT
                    R.Id as RID 
                    FROM    [User] as U
                                Inner Join
                            [Rooster] as R
                                On  R.UID = U.Id

                    WHERE       ([R].[L] BETWEEN @Ml AND @MXL)  
                            AND (0 =  [U].[Status])
                            AND (1 =  [U].[ActionStatus])
                            AND ((ABS((BINARY_CHECKSUM(R.Id,NEWID())))% 10000)/100 )  BETWEEN @R1 AND (@R1 + 10)
        ),
        tmp_two as
        (
            Select  tmp_one.RID as RID
                From    tmp_one
                Where   ((ABS((BINARY_CHECKSUM(RID,NEWID())))% 10000)/100 )  BETWEEN @R2 AND (@R2 + 10)
        ),
        tmp_three as
        (
            Select  RID as RID 
                From    tmp_two
                Where   ((ABS((BINARY_CHECKSUM(NEWID())))% 10000)/100 )  BETWEEN @R3 AND (@R3 + 10)
        ),
        tmp_four as
        (
            Select  TOP 100 RID as RID 
                From    tmp_three
                Where   ((ABS((BINARY_CHECKSUM(NEWID())))% 10000)/100 )  BETWEEN @R4 AND (@R4 + 10)
        )
        Select  TOP(10)
                RID
            From    tmp_four
            Order By RID
    End

我发现参数嗅探有问题! 我通过声明局部变量并将参数放在这些变量上来修复它。

一些关于 SQL 服务器参数嗅探的最佳文章: http://blogs.msdn.com/b/turgays/archive/2013/09/10/parameter-sniffing-problem-and-workarounds.aspx

http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx