2010-06-16 1 views
0

У меня есть sproc в SQL Server 2008. Это в основном строит строку, а затем выполняет запрос с помощью EXEC():Различные результаты Параметр Значение В Slow Query

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. Ни один подход не имел никакого значения.

Любые идеи?

UPDATE: Пытался бросить конкретные планы использования:

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 

Либо неправильные планы были сняты, или же планы в конечном итоге воссоздается, но это не имело никакого эффекта.

ответ

0

Выполнение UPDATE STATISTICS ... WITH FULLSCAN на основной базовой таблице в запросе привело к тому, что «медленное» значение не связано с медленным планом.

0

Проверьте распределение/частоту/мощность значений в столбце FStaffID и просмотрите свои индексы. Возможно, у вас есть один сотрудник, выполняющий 50% работы (возможно, DBA :), и это может изменить то, как оптимизатор выбирает, какие индексы использовать и как считывать данные.

В качестве альтернативы, план выполнения, сгенерированный динамическим кодом, может быть сохранен и повторно использован, что приводит к плохо выполняющемуся запросу (например, HLGEM говорит). Я не в деталях, но у SQL 2008 есть больше способов запутать вас, делая это, чем его предшественники.

+0

Фактически, если что-либо, более медленный запрос имеет меньше данных, чем другие. – alphadogg

+0

Есть ли способ найти, какие планы используются sproc, если они являются исключительными для этого sproc и отбрасывать их? – alphadogg

+0

DBCC FREEPROCCACHE отбросит * все * планы выполнения, которые в настоящее время хранятся в памяти. Я не верю, что есть способ выбрать и выбрать то, что выпало из этого кеша. Идентификация того, какой план используется или принадлежит тому, какой запрос является очень сложным и, возможно, невозможным, долгое время с тех пор, как я пытался. –