Почему план с ПОЛНОЙ оптимизацией показывает простую параметризацию?

8

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

Тогда почему этот план показывает полную оптимизацию и простую параметризацию одновременно?

NUTS

Эрик Дарлинг
источник

Ответы:

7

Простая параметризация предпринимается при обнаружении тривиального плана. Попытка параметризации может считаться безопасной или небезопасной .

Ключевым моментом является то, что тривиальный план найден и считается безопасным . Если стоимость тривиального плана превышает cost threshold for parallelism, оптимизатор перейдет к более поздним этапам оптимизации, где могут рассматриваться параллельные планы. Независимо от того, является ли конечный результат последовательным или параллельным планом, он будет просто параметризован, если будет параметризован безопасный тривиальный план, найденный ( но не использованный в конечном итоге ).

В примере с вопросом установка значения, cost threshold for parallelismпревышающего стоимость тривиального плана, позволит оптимизатору остановиться на этом этапе.


Глядя на план запроса не всегда достаточно, чтобы выяснить, был ли ваш запрос действительно параметризован.

Самый безопасный способ - это проверить некоторые DMV, чтобы проверить:

/*Unsafe auto param*/
SELECT *
FROM sys.dm_os_performance_counters AS dopc
WHERE dopc.counter_name LIKE '%Unsafe Auto-Params/sec%';

/*Safe auto param*/
SELECT *
FROM sys.dm_os_performance_counters AS dopc
WHERE dopc.counter_name LIKE '%Safe Auto-Params/sec%';

/*Trivial Plans*/
SELECT * 
FROM sys.dm_exec_query_optimizer_info AS deqoi 
WHERE deqoi.counter = 'trivial plan';

Кроме того, вы также можете использовать недокументированный флаг трассировки 8607, но не в качестве OPTIONподсказки для предложения. Использование OPTIONпредложения предотвращает тривиальный план.

DBCC TRACEON(8607, 3604);
/*Wait*/    

/*Run*/     
SELECT u.CreationDate, u.Id
FROM dbo.Users AS u
WHERE u.Reputation = 2;

/*Clean up*/
DBCC TRACEOFF(8607, 3604);

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

********************

** Query marked as Cachable

** Query marked as Safe for Auto-Param
Эрик Дарлинг
источник