У меня есть sproc в SQL Server 2008. Он в основном строит строку, а затем выполняет запрос, используя EXEC ():
SELECT * FROM [dbo].[StaffRequestExtInfo] WITH(nolock,readuncommitted)
WHERE [NoteDt] < @EndDt
AND [NoteTypeCode] = @RequestTypeO
AND ([FNoteDt] >= @StartDt AND [FNoteDt] <= @EndDt)
AND [FStaffID] = @StaffID
AND [FNoteTypeCode]<>@RequestTypeC
ORDER BY [LocName] ASC,[NoteID] ASC,[CNoteDt] ASC
Все, кроме @RequestTypeO и @RequestTypeF, передаются как параметры sproc. Два других встроены из параметра в локальные переменные. Обычно запрос выполняется менее одной секунды. Однако для одного конкретного значения @StaffID план выполнения отличается и примерно в 30 раз медленнее. В любом случае объем возвращаемых данных, как правило, одинаков, но время выполнения увеличивается.
Я пытался перекомпилировать sproc. Я также попытался «скопировать» @StaffID в локальный @LocalStaffID. Ни один из подходов не имел никакого значения.
Есть идеи?
ОБНОВЛЕНИЕ: Пытались отбросить определенные планы, используя:
DECLARE @ph VARBINARY(64), @pt VARCHAR(128), @sql VARCHAR(1024)
DECLARE cur CURSOR FAST_FORWARD FOR
SELECT p.plan_handle
FROM sys.[dm_exec_cached_plans] p
CROSS APPLY sys.dm_exec_sql_text(p.plan_handle) t
WHERE t.text LIKE N'%cms_selectStaffRequests%'
OPEN cur
FETCH NEXT FROM cur INTO @ph
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @pt = master.dbo.fn_varbintohexstr(@ph)
PRINT 'DBCC FREEPROCCACHE(' + @pt + ')'
SET @sql = 'DBCC FREEPROCCACHE(' + @pt + ')'
EXEC(@sql)
FETCH NEXT FROM cur INTO @ph
END
CLOSE cur
DEALLOCATE cur
Либо неправильные планы были отброшены, либо те же самые планы в конечном итоге были воссозданы, но это не имело никакого эффекта.