SQL 查询和存储过程执行后的读取次数显着不同
Posted
技术标签:
【中文标题】SQL 查询和存储过程执行后的读取次数显着不同【英文标题】:TSQL Number of reads significantly different after query and stored procedure execution 【发布时间】:2012-10-22 11:18:54 【问题描述】:在查询优化之后,我得到的结果是好的,我想改变存储过程,但是在 SP 执行之后得到的结果比查询执行之后更糟糕!
首先,我认为阅读次数。结果如此不同的原因是什么?
查询与SP中的相同,唯一的区别是在查询中我声明了参数,但在SP中是输入参数。设置为参数的值也相同。为了避免“记录数据”,我首先重新编译了 SP,然后进行了 DROP 和 CREATE,但结果也大不相同。
查询是这样的(表名和列名因为简化而改变,列数减少):
DECLARE @Var1 varchar(20)
SET @Var1 = @Var1 + '%'
DECLARE @Var2 TIMESTAMP
SELECT @Var2 = CONVERT(TIMESTAMP, ID, 0)
FROM
X_TIMESTAMPS (NOLOCK)
WHERE
TABLE = 'T1'
declare @Var3 varbinary(8)
SELECT @Var3 = max(IdTimeStamps)
FROM
T1 (NOLOCK)
SELECT o.c1
, o.c2
, o.c3
, v.c4
, v.c5
, p.c6
, p.c7
, va.c8
, isnull(s.c9, '') AS c9
, CASE o.c10
WHEN 1 THEN
0
ELSE
1
END c10
, o.c11
FROM
T1 o (NOLOCK)
JOIN T2 p (NOLOCK)
ON o.c1 = p.c12
JOIN T3 i (NOLOCK)
ON (o.c13 = i.c14)
JOIN T4 v (NOLOCK)
ON (v.c4 = i.c15)
LEFT JOIN T5 s (NOLOCK)
ON (o.c16 = s.c17)
JOIN T6 va (NOLOCK)
ON o.c11 = va.c18
WHERE
o.c1 LIKE @Var1
AND o.c2 > @Var2
程序是这样的:
CREATE PROCEDURE [dbo].[SP1] @Var1 varchar(20) =''
WITH RECOMPILE
AS
BEGIN
PREVIOUS QUERY WITHOUT DECLARATION FOR @Var1
END
提前TnX!
内曼加
【问题讨论】:
我们需要更多信息。 sp的代码是什么,命中了什么表,你做了什么优化,优化前的执行计划是什么,优化后是什么? 我编辑了问题并添加了查询和 SP。 【参考方案1】:这是因为不同的执行计划用于带常量的查询和带参数的sp。你可以尝试一些技巧
创建内联表函数并尝试一下
create function sf_test
(
@param1 int
)
returns table
as
return
your query using @in_param1
或
像这样在你的过程中声明额外的参数
create procedure sp_test
(
@param1 int
)
as
begin
declare @in_param1 int
select @in_param1 = @param1
your query using @in_param1
end
您也可以尝试在您的过程中使用选项with recompile
,或使用动态SQL
【讨论】:
就是这样!我添加了虚拟参数并正常继续执行。 @SpectralGhost 在另一个答案中添加的文章也非常有用,并详细解释了参数嗅探问题。 WITH RECOMPILE 之前尝试过,但在这种情况下没有用。【参考方案2】:这几乎肯定是parameter sniffing 问题。就个人而言,我喜欢使用虚拟变量选项来解决此问题,并且(仅当我遇到此问题时)创建设置为传入参数值的变量。
【讨论】:
那是参数嗅探问题!通过添加虚拟参数来解决。 TnX!以上是关于SQL 查询和存储过程执行后的读取次数显着不同的主要内容,如果未能解决你的问题,请参考以下文章