我有一个查询要放入存储过程中。当我使用局部变量运行查询时,查询大约需要 1 秒才能运行。当我将相同的查询放入存储过程并调用 SP 时,运行大约需要 2 分钟。
从SO中之前的问题来看,我认为这可能与参数嗅探有关。当我遇到这个问题之前,我在 SP 中声明了局部变量,然后在整个过程中使用了局部变量。这在过去有效,但在这种情况下似乎对我没有帮助。
我目前有
CREATE PROCEDURE dbo.ProcedureName
@DIV VARCHAR(4),
@STD VARCHAR(1), -- S or N
@scen varchar(20)
AS
BEGIN
DECLARE
@DIV_copy VARCHAR(4),
@STD_copy VARCHAR(1),
@scen_copy varchar(20);
SELECT
@DIV_copy = @DIV,
@STD_copy = @STD,
@scen_copy = @scen;
我也尝试过像这样添加
WITH RECOMPILE
CREATE PROCEDURE dbo.ProcedureName
@DIV VARCHAR(4),
@STD VARCHAR(1), -- S or N
@scen varchar(20)
WITH RECOMPILE
AS
BEGIN
DECLARE
@DIV_copy VARCHAR(4),
@STD_copy VARCHAR(1),
@scen_copy varchar(20);
SELECT
@DIV_copy = @DIV,
@STD_copy = @STD,
@scen_copy = @scen;
此外,我尝试在 SP 末尾添加
OPTION(RECOMPILE)
,如下所示:
SELECT *
FROM #Output
OPTION(RECOMPILE)
END
GO
我也尝试过使用:
OPTION(OPTIMIZE FOR UNKNOWN )
以及:
OPTION(QUERYTRACEON 4136)
在此选项中,我没有适当的查询跟踪权限。
上述 5 个修复似乎都无法解决该问题,因为对于在存储过程之外需要 1 或 2 秒的相同查询,存储过程仍然需要 2 分钟到 2 分 30 秒之间的时间。
这些修复全部来自这篇文章“纠正 SQL Server 参数嗅探的不同方法”
有人遇到过类似的问题吗?谢谢您的宝贵时间!
SQL Server 2008R2
不幸的是,我没有弄清楚为什么同一个查询放在存储过程中与单独的 sql 语句相比会遇到这么多麻烦。
作为“解决方法”,我花了一些时间优化 SP 中的查询。我意识到我要加入的一个表非常大(数百万行),所以我所做的就是从大表中获取相关数据并创建一个临时表来保存它,然后加入到(小得多)的临时表这似乎成功了。 SP 现在执行时间为 3-4 秒。
除了基础知识之外,我对 SQL 还有些陌生,所以我学到了很多东西。让它作为一个提醒来仔细检查您的查询,通常还有改进的空间。这感觉有点像透明胶带和回形针,但我的问题解决了。
谢谢大家的意见。
根据我的经验,在存储过程中运行查询而不出现性能问题的最佳方法是使用
运行它们sp_executesql
声明。