Кэширование планов выполнения SQL - PullRequest
3 голосов
/ 26 февраля 2010

Я знаю, что SQL Server 2005 выполняет некоторое количество операций кэширования плана выполнения, но будет ли этого достаточно, чтобы создать разницу в часах между одним и тем же запросом, выполняемым дважды? В первый раз это займет 3 часа, в следующий раз - 1 минута? Это вообще возможно?

Ответы [ 4 ]

3 голосов
/ 26 февраля 2010

SQL Server будет кешировать не только план выполнения, но и данные

если вы делаете

УСТАНОВИТЬ СТАТИСТИКУ IO ON

и посмотрите на вывод, который вы увидите логическое чтение и физическое чтение , логическое чтение - из ОЗУ, физическое чтение - с диска. Поэтому в первый раз вы увидите число для физических чтений, а если вы запустите его снова, вы увидите значение для логических чтений

3 часа кажется длинным, также может быть из-за блокировки / блокировки, устаревшей статистики и т. Д.

0 голосов
/ 27 февраля 2010

Нет. Скорее всего, в первый раз ваш запрос был заблокирован (например, другим сеансом или событием роста), а во второй раз - нет.

Чтобы привести пример, возьмите этот запрос: INSERT INTO Table (Field) VALUES (1). Простой запрос, но когда вы запускаете его в первый раз, база данных была заполнена и должна была расти. Размер базы данных составляет 750 ГБ, а по умолчанию она составляет 10%, поэтому необходимо создать 75 ГБ, поскольку учетной записи службы SQL Server не было предоставлено Выполнение задач обслуживания томов , поэтому рост длится около 30 минут. затем вы снова запускаете запрос, и он занимает меньше секунды.

Дело не в том, что у вас было или не было события роста, происходящего во время выполнения. Дело в том, что если запрос длится 3 часа, вам нужно понять, почему . Activity Monitor - отличное начало. Чтение белой книги, такой как Очереди ожидания при настройке производительности было бы еще лучше.

0 голосов
/ 26 февраля 2010

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

Во втором прогоне запроса («горячий прогон») использовались только данные из кэша, что, конечно, намного быстрее.

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

Скорее всего, другой план выполнения использовался во втором запуске (возможно, из-за обновления статистики).

0 голосов
/ 26 февраля 2010

НЕТ! Нет шансов!

Разница в другом месте!
Время, необходимое для составления плана запроса, составляет в лучшем случае порядка нескольких секунд (хуже).

По всей вероятности, разница обусловлена ​​либо:

  • кэшированные данные
  • наличие / отсутствие блокировок от других запросов / процессов
  • другой контекст данных при втором запуске запроса (ссылки на объекты SQL с меньшим количеством строк и т. Д.)

Упомянутая разница: 3 часа, до 1 минуты или около того, настолько радикальны, что я не думаю, что только кэшированные данные могут объяснить это .
Вот где поможет дополнительная информация о запросе ...
Например, и хотя этот запрос один и тот же выполнялся дважды, он может иметь другое поведение во второй раз (например, если это запрос типа update / insert / delete, он может не потребоваться изменить так много строк). Даже только запрос SELECT может выполняться иначе, потому что базовые данные были изменены (другими запросами / процессами).

Вот несколько предложений, чтобы узнать больше:

  • проверить (статически) сам план выполнения. Посмотрите, есть ли там что-то такое, что может быть таким дорогим, как 3 часа.
  • перезапустите запрос с «статистикой по» и очистив (или нет) кэши перед каждым запуском.

Заявления для очистки кэшей (могут быть другие способы сделать это с более новой версией SQL-Server):

dbcc freeproccache
go
dbcc dropcleanbuffers
go
...