web-dev-qa-db-ja.com

「where句」の評価順序を選択します

Sql Server 2005では、複数のパラメーターがある場合、評価順序が常に左から右になるという保証がありますか?

例を使用して:

select a from table where c=1 and d=2

このクエリでは、「c = 1」条件が失敗した場合、「d = 2」条件は評価されませんか?

PS-「c」は整数のインデックス付き列、dは大きなvarcharであり、テーブル全体のスキャンを必要とするインデックス付け不可能な列です。

pdate 2つのクエリまたは条件ステートメントの実行を回避しようとしていたので、次のようなものが必要です。「c条件」が失敗した場合、重い「d条件」の実行を回避する方法があります。私の場合。

26
t3mujin

評価順序の保証はありません。オプティマイザは、利用可能な情報を使用して、クエリを実行するための最も効率的な方法を見つけようとします。

あなたの場合、cは索引付けされており、dは索引付けされていないため、オプティマイザーは索引を調べてcの述語に一致するすべての行を見つけ、テーブル・データからそれらの行を取得してdの述語を評価する必要があります。

ただし、cのインデックスがあまり選択的でないと判断された場合(この例ではそうではありませんが、性別列が有用にインデックス付けされることはめったにありません)、とにかくテーブルスキャンを実行することを決定する場合があります。

実行順序を決定するには、クエリの説明プランを取得する必要があります。ただし、その計画は、オプティマイザーが現時点で最良のクエリであると考えるものに応じて変わる可能性があることに注意してください。

29
kdgregory

SQL Serverは、実行するステートメントごとに最適化された計画を生成します。その利点を得るためにwhere句を注文する必要はありません。あなたが持っている唯一の保証は、それが次のように順番にステートメントを実行するということです:

SELECT A FROM B WHERE C
SELECT D FROM E WHERE F

2番目の前に最初の行を実行します。

4
Orion Adrian

クエリの実行プランを見て、実際に何をしようとしているのかを判断できます。 SQL Serverのクエリエンジンはこのタイプのスキャンを実行することになっており、インテリジェントに操作に変換すると思います。同様に、「expensive-op AND false」を実行すると、すぐにfalseと評価されます。

私が学んだことから、あなたがタイプするものは実際に実行されるものとは異なります(そして異なる可能性があります)。期待する結果の種類をサーバーに伝えるだけです。それがどのように答えを得るかは、あなたが提供するコードの左から右への相関関係はありません。

2
Mark Canlas

確認したい場合は、 クエリ実行プラン を確認してください。 MSSQLが構築/最適化する実行プランは、varchar列の前にインデックス付き列をチェックするのに十分賢いです。

2
cgreeno

短絡は、参照している条件にリテラルまたは定数のみが含まれている場合に実行されます。たとえば、1から10までのすべての正の数を持つ列numを持つテーブルTableAがあるとします。次に、このクエリを記述します。

TableAからnumを選択します。WHERETableA.num<0 AND 1/0 = 10。

エラーになります。

コンパイラは、2番目の句が定数で構成されていると判断できるほど賢いので、テーブルまたはインデックスからのスキャンを必要とする句を評価する前に、それを評価する必要がありますか?

2
Nitin Midha

評価順序を制御する1つの方法は、CASE式を使用することです。

[編集]

私が表現しようとしていた世論は次のとおりです。

オプティマイザが最初の述語の前に2番目の述語を評価するプランを選択する可能性があるため、「WHERE OR」」のような式の評価順序に依存することはできません。ただし、式の評価順序はCASEステートメントは修正されているため、CASEステートメントの確定的な短絡評価に依存できます。

以下のサイトで説明されているように、それはそれよりも少し複雑になります:

http://blogs.msdn.com/b/bartd/archive/2011/03/03/don-t-depend-on-expression-short-circuiting-in-t-sql-not-even- with-case.aspx

1
Ric Tokyo

はい、MS SQLServerクエリオプティマイザは短絡します。保証付き。

これを実行します:

select 1 where 1 = 0 and 1 / 0 = 10

クエリオプティマイザはwhere句の評価を短絡するため、ゼロで除算してもエラーは発生せず、正常に実行されます。これは、「and」を実行していて、and部分の1つが定数であるwhere句に影響を及ぼします。

1
Robert C. Barth