SQL为什么sp比查询慢

时间:2015-04-07 09:34:20

标签: sql sql-server sql-server-2008 sql-server-2008-r2

这可能看起来很简单,但我确实需要帮助。我已经尝试了两天。

我将 userid 作为参数传递给存储过程并使用 userid 我正在检索 companyid 以在另一个查询中使用它。

CREATE PROC spXXXXXXX
@UserID INT
AS
BEGIN
DECLARE @CompanyID INT
SET @CompanyID =(SELECT CompanyID FROM User WHERE UserID=@UserID)

SELECT
            DISTINCT (U.UserID),
            U.UserName, 
            U.FirstName,
            U.LastName,
            C.CompanyName,
            U.Email,
            U.IsActive,
    FROM    
            [User] U
    LEFT OUTER JOIN 
            Company C
        ON
            C.CompanyID =U.CompanyID 
    WHERE   
            U.CompanyID=@CompanyID 
END  

执行需要30多秒。但如果我将值直接传递给查询,则只需1秒钟。 SET 需要更多时间才能执行。

所以我尝试使用CTE加速查询,但没有运气。同一时间。

;WITh cte(CompanyID)
        as
        (
        SELECT CompanyID FROM [User] WHERE UserID=@CurrentUserId
        ) 

   SELECT
            DISTINCT (U.UserID),
            U.UserName, 
            U.FirstName,
            U.LastName,
            C.CompanyName,
            U.Email,
            U.IsActive,
    FROM    
            [User] U
    LEFT OUTER JOIN 
            Company C
        ON
            C.CompanyID =U.CompanyID 
    LEFT OUTER JOIN 
            cte CS
        ON  
            CS.CompanyID =C.CompanyID
    WHERE   
            U.CompanyID=CS.CompanyID 

它还需要27秒才能返回31条记录。如果我直接传递这个值意味着它只需要一秒钟。我做错了什么?

2 个答案:

答案 0 :(得分:0)

通过使用中间变量,您可能会遇到隐式OPTION(OPTIMIZE FOR UNKNOWN)。见here。优化器没有以这种方式为您的查询提供良好的计划。

如果@CurrentUserID是变量而不是参数,那么第二个查询会遇到同样的问题。尝试此查询以查看它是否会表现更好:

CREATE PROC spXXXXXXX
    @UserID INT
AS
SELECT DISTINCT 
    U.UserID,
    U.UserName, 
    U.FirstName,
    U.LastName,
    C.CompanyName,
    U.Email,
    U.IsActive,
FROM [User] CU -- current user
INNER JOIN [User] U -- users with same company
ON      CU.CompanyID = U.CompanyID
LEFT JOIN Company C
ON      C.CompanyID =U.CompanyID 
WHERE   CU.[UserID] = @UserID

参数嗅探可能仍然存在一些问题,但这应该有助于优化器为您的过程生成更好的执行计划。

答案 1 :(得分:0)

尝试以下操作并查看是否有帮助...为用户创建局部变量,以避免参数嗅探。

declare @local_UserId int 
  select @local_UserId = @UserID

  DECLARE @CompanyID INT
    SET @CompanyID =(SELECT CompanyID FROM User WHERE UserID=@local_UserId)