web-dev-qa-db-ja.com

FULL最適化のプランが単純なパラメーター化を示すのはなぜですか?

私は 簡易プランは単純なパラメーター化が可能 であり、すべてのクエリが(プランが単純な場合でも) 単純なパラメーター化が可能 でないことを読みました。

では、なぜ この計画 は、完全な最適化と単純なパラメータ化を同時に示しているのですか?

NUTS

8
Erik Darling

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
7
Erik Darling