ランタイム定数
一度だけ評価されます。 GETDATE()
はそのような関数であり、DATEADD(..., constant, GETDATE())
実行時定数でもあります。クエリ内に実際の関数呼び出しを残すことで、オプティマイザーに(変数値のスニフではなく)実際に使用される値を確認させ、それに応じてカーディナリティの見積もりを調整して、より良い計画を立てることができます。
また、これを読んでください:不十分なクエリパフォーマンスのトラブルシューティング:カーディナリティ推定中の定数畳み込みと式の評価 。
@マーティンスミス
このクエリを実行できます:
set nocount on;
declare @known int;
select @known = count(*) from sysobjects;
declare @cnt int = @known;
while @cnt = @known
select @cnt = count(*) from sysobjects where getdate()=getdate()
select @cnt, @known;
私の場合、22秒後に境界ケースに到達し、ループが終了しました。重要なのは、ループが@cnt
で終了したことです。 ゼロ 。 getdate()
の場合、 行ごとに評価されると、正しい@knownカウントとは異なる@cntが取得されますが、0ではありません。ループが存在するときに@cntがゼロであるという事実は、各getdate()
を示しています。 が一度評価された後、すべての行のWHEREフィルタリングに同じ定数値が使用されました(一致なし)。 1つの肯定的な例が定理を証明しないことは承知していますが、このケースは十分に決定的なものだと思います。