SQL为什么sp比query慢
这个问题看起来很简单,但我真的需要帮助。我已经试了两天了 我将userid作为参数传递给存储过程,并使用该userid检索companyid以在另一个查询中使用它SQL为什么sp比query慢,sql,sql-server,sql-server-2008,sql-server-2008-r2,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.User
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秒。设置需要更多的时间来执行
因此,我尝试使用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
返回31条记录仍然需要27秒。如果我直接传递该值,则表示只需一秒钟。。我做错了什么 通过使用中间变量,您可能会遇到隐式选项(针对未知优化)。看见优化器没有以这种方式为您的查询提供良好的计划 如果
@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
您在参数嗅探方面可能仍然存在一些问题,但这将有助于优化器为您的过程生成更好的执行计划。尝试以下方法,看看是否有帮助。。。为用户创建局部变量,以避免参数嗅探
declare @local_UserId int
select @local_UserId = @UserID
DECLARE @CompanyID INT
SET @CompanyID =(SELECT CompanyID FROM User WHERE UserID=@local_UserId)
执行计划显示了什么?我猜引擎一开始使用的计划是错误的。您是否尝试过使用
ALTER PROC spXXXXXXX和RECOMPILE
选项更改存储过程?可能是,但基本上不可能不看执行计划就说。最简单的检查方法是标记重新编译的过程(EXECUTE sp_recompile N'spXXXXXXX'
),而不是强制它在每次执行时重新编译(就像with recompile
那样)这个查询不一样,在第二个示例中,您的@companyID
来自哪里?您应该将执行计划作为图像添加到问题中。添加表上所有索引的详细信息可能也很有用。每个表中有多少条记录?