私は 簡易プランは単純なパラメーター化が可能 であり、すべてのクエリが(プランが単純な場合でも) 単純なパラメーター化が可能 でないことを読みました。
では、なぜ この計画 は、完全な最適化と単純なパラメータ化を同時に示しているのですか?
trivialプランが見つかると、単純なパラメーター化が試行されます。パラメータ化の試みはsafeまたはnsafeと見なされます。
重要な点は、簡単な計画はfoundであり、safeと見なされることです。簡単な計画のコストが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);
プランがSimple Parameterizationに対して安全であると考えられる場合は、それを確認するメッセージがここに表示されます。
******************** ** Query marked as Cachable ** Query marked as Safe for Auto-Param