2011-01-27 13 views
0

システム:SQL Server 2008-R2SQL OR演算子の評価方法

私はその列の1つが "レベル"という名前のテーブルを持っています。 レベルは負数ではありません。

私は:

SELECT XXXXX 
FROM YYYYY 
WHERE (------------) AND 
     (Level >= @MinLevel) AND 
     (------------) 

私は正しい応答を取得します。

クエリを最適化するための試みで、私が実行しようとしました:

SELECT XXXXX 
FROM YYYYY 
WHERE (------------) AND 
     ((@MinLevel = 0) OR (Level >= @MinLevel)) AND 
     (------------) 

要求された最小レベルが0の場合は、クエリに最小 レベルの制限を追加し、そのことにより、保存する必要はありませんが(レベルにインデックスがないと仮定して)

実際には、「最適化されていない」クエリよりも長いクエリまたは少なくとも短いクエリではありません。

誰でも理由を説明できますか?

+0

'OPTION(RECOMPILE)を追加してみてください。違いはありますか? '@ MinLevel'もローカル変数またはパラメータですか? –

+0

おそらく、dbmsからクエリを最適化する作業をして、あなた自身でそれをやったからです。ほとんどの場合、dbmsはよく分かります。 – Femaref

+0

長い/短いクエリはどういう意味ですか?より長い実行時間またはより複雑な[実行計画](http://www.sql-server-performance.com/tips/query_execution_plan_analysis_p1.aspx)? '@MinLevel = 0'は大規模なデータセットを返さなければならないので、両方のクエリで同じ時間がかかると思うし、そのような単純な比較は通常非常に高速でほとんど気づかれないことがあります。ところで、あなたが必要とする最適化の種類は、[あなたの 'Level'カラムをインデックス化することです(http://msdn.microsoft.com/en-us/library/ms188783.aspx)です。 – Trinidad

答えて

2

ある質問は、SQLサーバ-2008-R2であるので、私たちは」優勝に評価する必要が を意味します他のDBMSも検討してください。

は、詳細な分析では、いくつかのために、ここで見てください:http://www.sommarskog.se/dyn-search-2008.html

それが問題に幾分関連する動的な検索を実行するための多くの方法について説明します。特に、この引用:

すべて@xの効果が 句NULL ISは、その入力 パラメータがNULLの場合、 AND-条件が常に真であることということです。 したがって、 の検索条件は、検索パラメータ がNULLでない値を持つ条件のみです。

....とパフォーマンスは? 非常に良い クエリヒントを含める限り OPTION(RECOMPILE)。

これは、セクションStatic SQLで発見されたとSQL 2008 R2 CU1 (10.50.1702) or laterに適用されます。

OPTION(RECOMPILE)ヒントを使用するクエリに同じ最適化ショートカット((@MinLevel = 0)の場合のみRHSを評価)が適用されます。

は、OR手術は通常、窓の外をインデックス化スロー

0

OR節はほとんどのDBMSでは最適化されていません。たとえば、インデックスは無視され、両方のケースが

ストレート> =ちょうどまっすぐ比較

0

を(これは質問に対するコメントで示唆されていることに気づきました)。

インデックスされたID列を持つ表があり、行ごとに1回カウントアップするとします。この表には100行あります。カラム> = 45

このクエリが有するWHERE SELECT *テーブルFROM:行1は、次に、このクエリを実行し、この列の値1を有し、そして100

の値を有するであろう100行であろう最初のレコードはテーブルの真ん中にあり、カラム値は50です。これは45には高すぎますが、テーブルの半分が削除されています見る必要はありません。次に、このグループの中央のレコードを調べます。この値は25です。これは低すぎますが、結果の半分が削除されました。

短いストーリーは、最初の45を見つけるためには、わずか6〜7行を見なければなりません。その後、結果セットとしてそこからテーブルの最後まですべての行が表示されます。コラム> = 45または列= 43

我々はもはや決定的なスタートポイントを持っているWHEREテーブルFROM SELECT *:

は今、このことがないように、そのクエリを微調整することができます。データベースは、結果を開始する特定の行を特定できません。どのレコードを返すかを決めるには、すべて行を調べて、それがあなたの必要条件と一致することを確認しなければなりません。一致する場合、結果にこの行が追加され、次の行に移動します。

+0

私の場合は分かりますが、私の場合はSPパラメータ(@MinLevel)と比較し、データベースの値とは比較しません。 – Gilad