Сегодня я наткнулся на интересную проблему с производительностью хранимой процедуры на Sql Server 2005 с пакетом обновления 2 (SP2) в БД, работающей на совместимом уровне 80 (SQL2000).
Процедура выполняется около 8 минут, и план выполнения показывает использование индекса с фактическим количеством строк 1.339.241.423, что примерно в 1000 раз больше, чем "реальный" фактический счетчик строк самой таблицы, который составляет 1.144.640. как показано правильно по приблизительному количеству строк. Таким образом, фактическое количество строк, заданное оптимизатором плана запросов, определенно неверно!
Интересно, что когда я копирую значения параметров procs внутри proc в локальные переменные и затем использую локальные переменные в реальном запросе, все работает нормально - proc выполняется 18 секунд, и план выполнения показывает правильное действительное количество строк.
РЕДАКТИРОВАТЬ: Как предполагает TrickyNixon, это, кажется, признак проблемы перехвата параметров. Но на самом деле я получаю в обоих случаях один и тот же план выполнения. Одни и те же индексы используются в том же порядке. Единственное различие, которое я вижу, - это путь к большому фактическому количеству строк в индексе PK_ED_Transitions при непосредственном использовании значений параметров.
Я уже выполнил dbcc dbreindex и UPDATE STATISTICS без какого-либо успеха.
dbcc show_statistics также показывает хорошие данные для индекса.
Процедура создается с RECOMPILE, поэтому при каждом запуске новый план выполнения компилируется.
Чтобы быть более конкретным - этот работает быстро:
CREATE Proc [dbo].[myProc](
@Param datetime
)
WITH RECOMPILE
as
set nocount on
declare @local datetime
set @local = @Param
select
some columns
from
table1
where
column = @local
group by
some other columns
И эта версия работает очень медленно, но выдает точно такой же план выполнения (кроме слишком большого фактического числа строк в используемом индексе):
CREATE Proc [dbo].[myProc](
@Param datetime
)
WITH RECOMPILE
as
set nocount on
select
some columns
from
table1
where
column = @Param
group by
some other columns
Есть идеи?
Кто-нибудь знает, откуда Sql Server получает фактическое значение числа строк при расчете планов запросов?
Обновление : Я пытался выполнить запрос на другом сервере, для которого установлен режим copat 90 (Sql2005). Это то же самое поведение. Я думаю, что открою службу поддержки MS, потому что это выглядит для меня как ошибка.