2

varbinary列のデータに関する一連の行を返すストアドプロシージャを使用しています。私の人生では、を使用するときにクエリ時間が常に同じ割合で増加する理由を理解することはできませsp_executesqlexec

時間のあるクエリsp_executesql:<1秒、1秒、2秒、4秒、8秒、24秒(など)、最終的に問題が数分間「解消」され、クエリが常に〜0.006秒になるまで

のクエリ時間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

私が知る限り、sprocが呼び出される2つの方法は基本的に同じです。唯一の違いはsp_executesqlvsですexec

また、最後にキーワードが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 に答える