Когда вы включите опцию « Оптимизировать для специальных рабочих нагрузок », вы сделаете так, что специальные запросы, которые выполняются во второй раз, будут такими же медленными, как и первый, потому что вы будете компилировать план выполнения и извлекать те же данные ( без этого кешируется) те первые 2 раза.
Это может не иметь большого значения, но вы заметите это при тестировании запросов.
Так что же происходит сейчас, если эта опция не включена, а кэш заполнен одноразовыми специальными запросами?
Алгоритм управления кэшированием:
По мере появления этой функции оптимизации был также обновлен алгоритм управления кэшированием.
Статья Кимберли Триппа также ссылается на пост Калена Делани об этом изменении алгоритма.
Она объясняет это лучше всего:
Это изменение фактически вычисляет размер кэша плана, при котором SQL Server распознает наличие нехватки памяти и начинает удалять планы из кэша. Планы, которые будут удалены, - это дешевые планы, которые не использовались повторно, и это ХОРОШО.
Это означает, что эти надоедливые планы с одним таймером будут первыми, когда вам понадобится освободить ресурсы.
Итак, теперь возникает вопрос:
« Почему нам НУЖНО« Оптимизировать для специальных рабочих нагрузок », когда SQL Server позаботится об удалении неиспользуемых планов, когда это необходимо? »
Мой ответ на этот вопрос заключается в том, что если у вас регулярно есть тонна динамического sql, генерирующего кучу непараметрической рекламы -hoc запросов, тогда имеет смысл включить эту функцию.
Вы хотите избежать нагрузки на системные ресурсы, так как это приведет к удалению кэшированного плана / данных после того, как вы израсходуете максимальное пространство кеш-памяти.
Как узнать, когда мне нужно включить это?
Вот запрос, который я написал, чтобы показать вам, сколько Ad-Hoc планов вы сейчас кэшировали и сколько дискового пространства они потребляют (результаты будут меняться в течение дня - так что тестируйте его во время большой нагрузки):
--Great query for making the argument to use "Optimize for Ad Hoc Workloads":
SELECT S.CacheType, S.Avg_Use, S.Avg_Multi_Use,
S.Total_Plan_3orMore_Use, S.Total_Plan_2_Use, S.Total_Plan_1_Use, S.Total_Plan,
CAST( (S.Total_Plan_1_Use * 1.0 / S.Total_Plan) as Decimal(18,2) )[Pct_Plan_1_Use],
S.Total_MB_1_Use, S.Total_MB,
CAST( (S.Total_MB_1_Use * 1.0 / S.Total_MB ) as Decimal(18,2) )[Pct_MB_1_Use]
FROM
(
SELECT CP.objtype[CacheType],
COUNT(*)[Total_Plan],
SUM(CASE WHEN CP.usecounts > 2 THEN 1 ELSE 0 END)[Total_Plan_3orMore_Use],
SUM(CASE WHEN CP.usecounts = 2 THEN 1 ELSE 0 END)[Total_Plan_2_Use],
SUM(CASE WHEN CP.usecounts = 1 THEN 1 ELSE 0 END)[Total_Plan_1_Use],
CAST((SUM(CP.size_in_bytes * 1.0) / 1024 / 1024) as Decimal(12,2) )[Total_MB],
CAST((SUM(CASE WHEN CP.usecounts = 1 THEN (CP.size_in_bytes * 1.0) ELSE 0 END)
/ 1024 / 1024) as Decimal(18,2) )[Total_MB_1_Use],
CAST(AVG(CP.usecounts * 1.0) as Decimal(12,2))[Avg_Use],
CAST(AVG(CASE WHEN CP.usecounts > 1 THEN (CP.usecounts * 1.0)
ELSE NULL END) as Decimal(12,2))[Avg_Multi_Use]
FROM sys.dm_exec_cached_plans as CP
GROUP BY CP.objtype
) AS S
ORDER BY S.CacheType
Результаты:
Я не буду говорить « Когда у вас есть X МБ » или « Если X% вашего Ad Hoc одноразового использования », чтобы включить это.
Это не влияет на Sprocs, Triggers, Views или Parameterized / Prepared SQL - только на специальные запросы.
Моя личная рекомендация - просто включить ее в вашей среде Prod, но подумайте о том, чтобы отключить ее в вашей среде разработки.
Я говорю это только для Dev, потому что если вы оптимизируете запрос, выполнение которого занимает минуту или более, вы не хотите запускать его 3 раза, прежде чем увидите, как быстро он будет выполняться с кэшированием - каждый один раз, когда вы редактируете его, чтобы найти лучший дизайн оптимизации.
Если ваша работа не связана с этим весь день, то сходите с ума и попросите вашего БД включить его везде.