2015-04-07 139 views
1

这看起来很简单,但我真的需要帮助。我一直在尝试这两天。SQL为什么sp比查询要慢

我传递用户ID作为参数传递给存储过程,并使用用户ID 我检索companyid在另一个查询使用它。

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

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 
      [email protected] 
END 

它需要多于30秒至execute.but如果我直接传递的值与查询然后只需要1秒。 SET需要更多时间来执行。

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

;WITh cte(CompanyID) 
     as 
     (
     SELECT CompanyID FROM [User] WHERE [email protected] 
     ) 

    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条记录。如果我直接传递值意味着它只需要一秒。我做错了什么?

+0

执行计划显示什么? – Richard

+0

我想引擎使用错误的计划开始。您是否尝试使用'ALTER PROC spXXXXXXX WITH RECOMPILE'选项更改存储过程。 ? – SouravA

+0

可能[参数嗅探](http://sqlperformance.com/2013/08/t-sql-queries/parameter-sniffing-embedding-and-the-recompile-options),基本上不可能说没有看到执行计划虽然。最简单的方法来检查将标记重新编译的程序('EXECUTE sp_recompile N'spXXXXXXX''),而不是强迫它与每次执行重新编译(如'WITH RECOMPILE'会) – GarethD

回答

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 

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

0

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

declare @local_UserId int 
    select @local_UserId = @UserID 

    DECLARE @CompanyID INT 
    SET @CompanyID =(SELECT CompanyID FROM User WHERE [email protected]_UserId) 
相关问题