Было бы лучше, чтобы планы запросов были разделены по заявлению на повторное использование?

11

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

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

Мой вопрос: если пользователь выполняет оператор, который является одним из операторов в запросе с несколькими операторами, может ли он использовать эту релевантную часть плана запроса, уже находящуюся в кэше, для запроса с несколькими операторами? Я ожидаю, что ответ будет отрицательным, потому что значения хеш-функции, очевидно, не будут совпадать, но лучше ли будет хэшировать каждый оператор в запросе с несколькими операторами, чтобы они могли использоваться пользователями, выполняющими отдельные операторы из запроса?

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

Может быть, просто показывая мое невежество, хотя.

Джеймс Андерсон
источник
dbidи то, и objectidдругое is_cache_key=1так, что вы не сможете повторно использовать планы между различными скомпилированными объектами.
Мартин Смит

Ответы:

11

Если пользователь выполняет оператор, который является одним из операторов в запросе с несколькими операторами, может ли он использовать эту релевантную часть плана запроса, уже находящуюся в кэше, для запроса с несколькими операторами?

Нет. Основной единицей повторного использования плана в SQL Server является пакет .

Будет ли лучше хешировать каждый оператор в запросе с несколькими операторами, чтобы они могли использоваться пользователями, выполняющими отдельные операторы из запроса?

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

Я ожидаю, что есть осложнения, которые я не принимаю во внимание

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

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

Пол Уайт 9
источник