2

我正在使用一个存储过程来返回一组关于 varbinary 列中的数据的行。在我的一生中,我无法弄清楚为什么当我使用sp_executesql而不是exec.

查询sp_executesql时间:<1s, 1s, 2s, 4s, 8s, 24s (etc), 直到最终问题“消失”几分钟并且查询总是~0.006s

查询时间exec总是<500ms。

起初,我认为这是 Linq2Sql 的问题,但是当我们在 SQL Management Studio 中运行 Linq 生成的查询时,我们得到了相同的结果。

这是 sproc 的主体(经过严格审查)

请注意,该varbinary列没有被拉出

select DF.FileID, 
       DF.DerpFkGuid, 
       DF.DerpName, 
       DF.[FileName],
       DF.FileSize as 'FileSizeBytes', 
       ISNULL(DFA.File_Size_Bytes_String,'Unknown') as 'FileSizeFriendly', 
       CONVERT(nvarchar(30),DF.FoundDate,120) as 'FileDateUploaded', 
       CONVERT(nvarchar(30),DF.FileDateCreated,120) as 'FileDateCreated',
       CONVERT(nvarchar(30),DF.FileDateLastModified,120) as 'FileDateModified',
       CASE WHEN ISNULL(dfa.Derp_ID,'00000000-0000-0000-0000-000000000000')='00000000-0000-0000-0000-000000000000' THEN 0 ELSE 1 END as 'AttachedToDerp', 
       ISNULL(dfa.Derp_ID,'{00000000-0000-0000-0000-000000000000}') as 'Derp_ID'
from DerpFiles DF   
inner join DFDerpDerp DFdd      on DFdd.DerpName = DF.DerpName
left outer join Derp_Files_Attachments dfa      on dfa.FileID =  DF.FileID
where WR.UserName = @UserName and DF.DuplicateFileDetected=0

这是始终运行 < 500ms 的代码

USE [DerpDatabase]
GO

DECLARE @return_value int

EXEC    @return_value = [dbo].[DerpSproc]
        @UserName = N'derp',
        @DomainName = N'derp'

SELECT  'Return Value' = @return_value

GO

这是运行 1s ,2s ,4s, 8s , 24s 等的代码

declare @p5 int
set @p5=0
exec sp_executesql N'EXEC   @RETURN_VALUE = [dbo].[DerpSproc] 
                            @UserName = @p0, 
                            @DomainName = @p1',                         
                            N'@p0 nvarchar(4000),
                            @p1 nvarchar(4000),
                            @RETURN_VALUE int output',
                            @p0=N'derp',
                            @p1=N'derp',
                            @RETURN_VALUE=@p5 output
select @p5

据我所知,调用存储过程的两种方式基本相同。唯一的区别是sp_executesqlvsexec

在没有关键字的情况下,它似乎exec也会产生同样增加的查询时间。go我不能确定,因为我不知道当我尝试添加时查询是否恰好缓存go

4

2 回答 2

1

这可能是参数嗅探问题。有时,当您将参数传递给过程时,SQL 很难弄清楚如何有效地使用它们。尝试在过程中将参数设置为局部变量,然后在 where 子句中使用局部变量。

参数嗅探

于 2012-08-16T22:39:22.143 回答
0

我们通过将VARBINARY字段从文件表移动到它自己的专用表来解决我们的问题。如果查询时间不长,我们就无法在文件表和元数据表之间添加适当的关系。

这只发生在我们将查询作为存储过程执行时。WHERE当我们执行与带有过滤器子句的视图相同的精确查询时,不会发生这种情况。我们受过良好教育的理论是 SQL Server 2012 有一个错误(?)导致VARBINARY我们连接的表中的字段在我们的查询中被读取,即使它没有包含在我们的SELECT语句中。

于 2012-08-16T20:06:41.220 回答