Каждый план выполнения является предполагаемым планом

Пересказ статьи Grant Fritchey. Every Execution Plan Is An Estimated Plan

Давайте поговорим о различных планах, которые можно получить в SQL Server.

Предполагаемый план (Estimated Plan)

Для генерации этого плана вместо выполнения запроса, пакета, хранимой процедуры вы в SQL Server Management Studio (SSMS) используете кнопку “Display Estimated Execution Plan” (показать предполагаемый план выполнения).

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

Кэшированные планы

Большинство планов, но не все, находятся в кэше планов в памяти. Вы можете получить доступ к этим планам с помощью sys.dm_exec_query_plan или sys.dm_exec_query_plan_text. Это планы, которые использовались движком запросов для извлечения или модификации ваших данных. Однако эти планы не содержат информации времени исполнения. Следовательно, они являются предполагаемыми планами. Но, опять таки, как было отмечено ранее, вы можете увидеть различия между этими планами и генерируемыми вами предполагаемыми планами, главным образом, в свойствах, но не в общей форме плана. Эти различия зависят от того, находится ли план в кэше, когда вы запрашиваете предполагаемый план. Если план находится в кэше, вы получите этот кэшированный план. Если плана нет в кэше, вы получите план, сгенерированный оптимизатором. Различия при выполнении означают разницу в статистических величинах, что может отразиться на оценках количества строк. Фактически, вы можете даже увидеть радикально различные формы планов. Однако это вызывается изменением ваших данных и статистики, а не тем, как генерировался план.

И хотя это планы, используемые движком запросов, они являются предполагаемыми планами, поскольку не содержат метрик времени выполнения.

Планы в хранилище запросов

Планы сохраняются в хранилище запросов в том виде, в каком они генерируются, и хранятся в кэше как часть выполнения запроса. По умолчанию до SQL Server 2019 все планы туда помещались. Начиная с 2019 настройкой по умолчанию является сохранение планов, которые выполняются наиболее долго выполняются или наиболее часто вызываются. Вы также имеете больше возможностей управлять этим.

Однако планы, которые сохраняются, не имеют метрик времени исполнения. Следовательно, они являются предполагаемыми планами. Да, если сравните эти планы с планами, которые вы получаете генерацией предварительного плана или извлекая план из кэша, вы можете увидеть различия в свойствах. Скажу еще раз, тут мы говорим о временных проблемах. Если мы не имеем полностью статическую систему (подобную тестовой, где ничего никогда не меняется), то статистические изменения в оценках строк обычны и выражаются в некоторых различиях, возможно даже существенных различиях, между планами в хранилище запросов (Query Store) и другими типами планов.

Я просто должен указать еще раз, что, хотя это планы, которые использовались при первоначальном выполнении запроса, отсутствие метрик времени выполнения делает их предполагаемыми планами.

Действительные планы

Вы должны выполнить запрос, чтобы получить действительный план выполнения (за исключением новой функциональности в SQL Server 2019). Это обусловлено тем, что действительные планы определяются метриками времени выполнения; фактическое число строк и т.п. С этими метриками времени выполнения вы получаете действительный план. Без этих метрик времени выполнения вы видите предварительный план.

В зависимости от того, как и когда вы снимаете действительный план, вы можете увидеть разницу между ним и предварительными планами, также зависящими от того, когда они были построены. На это влияет время и, следовательно, данные и метод. Например, действительные планы, полученные с помощью расширенных событий или трассировки, отличаются по структуре от планов, полученных с помощью SSMS (или в 2019 году). Нет, я не знаю почему. Когда я последний раз разговаривал с инженерами Майкрософт, они были этим удивлены, так что я не уверен, что они тоже знают почему. Вы также можете увидеть различия, малые или большие, из-за перекомпиляции (автоматической или принудительной) процедуры, пакета или просто оператора. Опять таки эти различия вызываются, главным образом, изменением данных, что приводит к изменению плана, а не различием представлений между предварительным и действительным планами.

Даже действительные планы — это только предварительные планы с добавленными показателями времени выполнения. Вот почему оценки стоимости неточно соответствуют реальному числу строк, давая вам быстрое указание на точность и эффективность данного плана посредством сравнения предварительных оценок с фактическими значениями.

Заключение

Да, есть куча мелких деталей, которые также могут повлиять на точность сравнения предполагаемых и фактических значений. На них влияют такие вещи, как навязывание плана, руководство планом и многое другое. Тем не менее, ни одна из них не меняет фундаментальные принципы. Есть планы с показателями времени выполнения и планы без показателей времени выполнения. Планы с показателями времени выполнения в настоящее время называются действительными планами. Планы без метрик времени выполнения в настоящее время называются предполагаемыми планами. Возможно, в будущем мы сможем получить более точные названия для них.

Добавить комментарий