Генерация плана SQL-запроса занимает 5 минут, сам запрос работает в миллисекундах.Как дела?

У меня есть довольно сложное (или ужасный в зависимости от того, как Вы смотрите на него), хранимая процедура, работающая на SQL Server 2008. Это основывает большую логику на представлении, которое имеет pk таблицу и fk таблицу. Из-за fk стола встают соединенный с pk таблицей немного больше чем 30 раз (fk таблица имеет плохой дизайн - это использует пары значение-имя, которые я должен выровнять. К сожалению, это - третья сторона, и я не могу изменить его).

Так или иначе это хорошо работало в течение многих недель, пока я периодически не замечал выполнение, которое займет 3-5 минут. Оказывается, что это - время, которое требуется для генерации плана запросов. После того как план запросов существует и кэшируется, сама хранимая процедура работает очень эффективно. Вещи, выполненные гладко до, существуют причина повторно создать и кэшировать план запросов снова.

Кто-либо видел это? Почему это занимает много времени для генерации плана? Там пути состоят в том, чтобы заставить его придумать план быстрее?

10
задан TheEmirOfGroofunkistan 12 April 2010 в 16:27
поделиться

3 ответа

Что-то заставило план потребовать перекомпиляции, например обновление статистики или изменение DDL. Список, если здесь: Кэширование и повторное использование плана выполнения

Запрос в его текущей форме всегда будет перекомпиляция займет 3-5 минут: этого нельзя избежать.

Предполагая, что вы не можете его изменить (PIVOT, использовать триггер для поддержания «правильной» таблицы и т. Д.), Тогда вы можете контролировать только то, когда происходит перекомпиляция.

Ответ Ремуса по плану - односторонний. Я бы также посмотрел на мое ведение статистики и убедился, что это делается за ночь, скажем, так, чтобы это происходило только один раз в начале дня

3
ответ дан 4 December 2019 в 01:56
поделиться

Вы не думали переписать ваш 30-join SELECT на что-то вроде этого?

SELECT [key], NULL AS [a], NULL AS [b]
  INTO #temp
  FROM [pk-table]

UPDATE t SET t.[a] = fk.[a], t.[b] = fk.[b]
  FROM #temp t
  INNER JOIN (
    SELECT f.[key],
      MAX(CASE WHEN f.[name] = 'a' THEN f.[value] ELSE NULL END) AS [a],
      MAX(CASE WHEN f.[name] = 'b' THEN f.[value] ELSE NULL END) AS [b]
    FROM [fk-table] f
    GROUP BY f.[key]
    ) fk ON (fk.[key] = t.[key]

Хотя, возможно, это не ответ на ваш первоначальный вопрос :)

2
ответ дан 4 December 2019 в 01:56
поделиться

Вы можете попробовать использовать Plan Guide. Генерация плана все равно будет длиться некоторое время, но значительно меньше.

4
ответ дан 4 December 2019 в 01:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: