2012-08-16 89 views
2

我正在使用一個存儲過程來返回有關varbinary列中數據的一組行。對於我的生活,我無法弄清爲什麼當我使用sp_executesql而不是exec時,查詢時間總是以相同的速度增加。存儲過程的查詢時間越來越長。 - EXEC與SP_EXECUTESQL

查詢與sp_executesql時間去:< 1S,1S,2S,4S,8S,24S(ETC)直到最後,這個問題 「消失」 了幾分鐘,查詢是總是〜0.006s

exec的查詢時間總是< 500ms。

起初,我認爲這是Linq2Sql的問題,但是當我們運行Linq在SQL Management Studio中生成的查詢時,我們得到了相同的結果。

這裏的存儲過程(嚴格審查)

注意,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', 
          @[email protected] output 
select @p5 

據我所知,sprocs被調用的2種方式基本上是相同的。唯一的區別是sp_executesql VS exec

還可以看出exec會產生相同的增加查詢時間沒有在最後的go關鍵字。我無法確定,因爲我不知道查詢是否發生緩存,當我嘗試添加go

+0

整個之所以使用'sp_executesql'是利用語句緩存的,並且據我所知,這是與'exec'唯一的區別是這樣。所以我打賭這個問題以某種方式觸發了緩存查詢處理方式中的錯誤? – kprobst 2012-08-16 16:33:49

回答

1

這可能是一個參數嗅探問題。有時,當你將參數傳遞給一個過程時,SQL很難弄清楚如何有效地使用它們。嘗試將過程中的參數設置爲局部變量,然後在where子句中使用局部變量。

Parameter Sniffing

0

我們通過將文件列表中的VARBINARY字段移至其專用表中解決了我們的問題。我們無法在查詢時間不經過屋頂的情況下在文件表和元數據表之間添加適當的關係。

這隻發生在我們將查詢作爲存儲過程執行時。當我們使用與我們的過濾器的WHERE子句相同的確切查詢作爲視圖時,不會發生這種情況。我們受過良好教育的理論是,SQL Server 2012有一個錯誤(?),導致我們連接的表中的VARBINARY字段在我們的查詢中被讀取,即使它不包含在我們的SELECT聲明中。