【发布时间】:2015-04-07 09:34:20
【问题描述】:
这可能看起来很简单的问题,但我真的需要帮助。我已经尝试了两天了。
我将 userid 作为参数传递给存储过程,并使用该 userid 检索 companyid 以在另一个查询中使用它。 p>
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
返回 31 条记录仍然需要 27 秒。如果我直接传递值意味着只需要一秒钟..我做错了什么?
【问题讨论】:
-
执行计划显示什么?
-
我猜引擎一开始就使用了错误的计划。您是否尝试使用
ALTER PROC spXXXXXXX WITH RECOMPILE选项更改存储过程。 ? -
可能是parameter sniffing,但基本上不可能说没有看到执行计划。最简单的检查方法是标记重新编译的过程(
EXECUTE sp_recompile N'spXXXXXXX'),而不是强制它重新编译每次执行(如WITH RECOMPILE那样) -
这个查询不一样,你的
@companyID在第二个例子中来自哪里? -
您应该将执行计划作为图像添加到您的问题中。添加您在表上拥有的任何索引的详细信息也可能很有用。每张表有多少条记录?
标签: sql sql-server sql-server-2008 sql-server-2008-r2