158

SQL WHERE 句のブール式は短絡評価され ますか?

例えば:

SELECT * 
FROM Table t 
WHERE @key IS NULL OR (@key IS NOT NULL AND @key = t.Key) 

@key IS NULLが に評価される場合true、評価@key IS NOT NULL AND @key = t.Keyされますか?

いいえの場合、なぜですか?

はいの場合、それは保証されていますか?ANSI SQL の一部ですか、それともデータベース固有ですか?

データベース固有の場合、SQLServer? オラクル?MySQL?

4

15 に答える 15

80

ANSI SQL ドラフト 2003 5WD-01-Framework-2003-09.pdf

6.3.3.3 ルールの評価順序

[...]

フォーマットまたは括弧によって優先順位が決定されない場合、式の効果的な評価は通常、左から右に実行されます。ただし、式が実際に左から右に評価されるかどうかは 実装に依存します。特に、オペランドまたは演算子によって条件が発生する可能性がある場合や、式のすべての部分を完全に評価しなくても式の結果を判断できる場合はそうです。

于 2009-05-26T09:23:41.583 に答える
64

上記のことから、短絡は実際には利用できません。

必要な場合は、Case ステートメントをお勧めします。

Where Case when Expr1 then Expr2 else Expr3 end = desiredResult

Expr1は常に評価されますが、行ごとに評価されるのはExpr2との 1 つだけです。Expr3

于 2012-09-07T15:10:10.943 に答える
19

これは、3つの理由から、短絡していないかのように書く場合の1つだと思います。

  1. MSSQLの場合、明らかな場所でBOLを確認しても解決されないため、私にとっては、それが標準的にあいまいになります。

  2. 少なくともその時、私は自分のコードが機能することを知っているからです。そしてもっと重要なことは、私の後に来る人たちもそうするので、私は彼らに同じ質問を何度も何度も心配するように設定していません。

  3. 私はいくつかのDBMS製品について十分な頻度で書いていますが、それらを簡単に回避できれば、違いを覚えておく必要はありません。

于 2009-04-25T18:06:27.180 に答える
12

SQL Server (2005) での短絡が保証されているとは思えません。SQL Server は、多くのこと (インデックス、統計、テーブル サイズ、リソースなど) を考慮した最適化アルゴリズムを使用してクエリを実行し、効果的な実行計画を作成します。この評価の後、短絡ロジックが保証されているとは言えません。

少し前に同じ質問に出くわしましたが、私の調査では決定的な答えが得られませんでした. 小さなクエリを作成して、それが機能することを証明する感覚を得ることができますが、データベースの負荷が増加するにつれて、テーブルが大きくなり、データベース内で物事が最適化および変更されることを確信できますか?所有。私はできなかったため、注意を怠り、WHERE句でCASEを使用して短絡を確実にしました。

于 2009-04-25T16:43:56.130 に答える
7

データベースがどのように機能するかを覚えておく必要があります。パラメータ化されたクエリが与えられると、db はパラメータの値なしでそのクエリに基づいて実行プランを構築します。このクエリは、実際に提供された値に関係なく、クエリが実行されるたびに使用されます。クエリが特定の値で短絡するかどうかは、実行計画にとって重要ではありません。

于 2009-04-25T23:58:47.880 に答える
4

私は通常、これをオプションのパラメーターに使用します。これは短絡と同じですか?

SELECT  [blah]
FROM    Emp
WHERE  ((@EmpID = -1) OR (@EmpID = EmpID))

これにより、属性のオプションのチェックを説明するために -1 などを渡すオプションが与えられます。場合によっては、これには複数のテーブル、またはできればビューでの結合が含まれます。

非常に便利ですが、db エンジンに与える余分な作業については完全にはわかりません。

于 2009-04-28T20:22:38.203 に答える
4

この質問につまずいて、すでにこのブログエントリを見つけていました:http://rusanu.com/2009/09/13/on-sql-server-boolean-operator-short-circuit/

SQL サーバーは、適切と思われる場所ならどこでもクエリを自由に最適化できるため、ブログ投稿に示されている例では、ショートサーキットに頼ることはできません。

ただし、CASE は書面による順序で評価するように文書化されているようです。そのブログ投稿のコメントを確認してください。

于 2012-08-14T19:33:27.387 に答える
2

SQL Server の場合、バージョンにもよると思いますが、SQL Server 2000 での私の経験では、@key が null の場合でも @key = t.Key を評価します。つまり、WHERE 句を評価するときに効率的な短絡を行いません。

ユーザーがさまざまな基準を入力または入力できない柔軟なクエリを実行する方法として、あなたの例のような構造を推奨している人を見てきました。私の観察では、 @key が null の場合でも Key は引き続きクエリ プランに関与しており、Key にインデックスが付けられている場合、インデックスは効率的に使用されません。

さまざまな基準を持つこの種の柔軟なクエリは、おそらく、動的に作成された SQL が実際に最善の方法である 1 つのケースです。@key が null の場合は、クエリにまったく含めないでください。

于 2009-04-25T16:32:26.643 に答える
1

短絡評価の主な特徴は、結果が決定されるとすぐに式の評価を停止することです。つまり、評価されるかどうかに関係なく結果は同じになるため、残りの式は無視できます。

バイナリブール演算子は可換です。つまり、次のようになります。

a AND b == b AND a
a OR  b == b OR  a
a XOR b == b XOR a

したがって、評価の順序についての保証はありません。評価の順序は、クエリオプティマイザによって決定されます。

オブジェクトのある言語では、短絡評価でのみ評価できるブール式を記述できる場合があります。サンプルコードの構成は、このような言語(C#、Delphi、VB)でよく使用されます。例えば:

if(someString == null | someString.Length == 0 )
  printf("no text in someString");

このC#の例は、someString == null完全に評価されるため、例外が発生します。短絡評価では、毎回動作します。

SQLは、初期化を解除できないスカラー変数(オブジェクトなし)でのみ動作するため、評価できないブール式を作成する方法はありません。NULL値がある場合、比較するとfalseが返されます。

つまり、SQLでは、短絡または完全評価の使用によって評価が異なる式を記述できません。

SQL実装で短絡評価を使用する場合、クエリの実行を高速化することしかできません。

于 2009-04-25T18:25:23.080 に答える
1

ショートサーキットについてはわかりませんが、if-elseステートメントとして記述します

if (@key is null)
begin

     SELECT * 
     FROM Table t 

end
else
begin

     SELECT * 
     FROM Table t 
     WHERE t.Key=@key

end

また、変数は常に方程式の右側にある必要があります。これにより、サーガブルになります。

http://en.wikipedia.org/wiki/Sargable

于 2009-04-25T22:58:04.267 に答える
1

以下は、SQL Server 2008 R2 での簡単で汚いテストです。

SELECT *
FROM table
WHERE 1=0
AND (function call to complex operation)

これは、レコードなしですぐに返されます。ある種の短絡動作が存在しました。

次に、これを試しました:

SELECT *
FROM table
WHERE (a field from table) < 0
AND (function call to complex operation)

レコードがないことを知っていると、次の条件が満たされます。

(a field from table) < 0

これには数秒かかりました。これは、短絡動作がもはや存在せず、レコードごとに複雑な操作が評価されていることを示しています。

これがみんなに役立つことを願っています。

于 2012-07-25T14:27:42.733 に答える
0

これには、クエリ アナライザーでさらに 4 秒かかるため、IF が短縮されていないことがわかります...

SET @ADate = NULL

IF (@ADate IS NOT NULL)
BEGIN
    INSERT INTO #ABla VALUES (1)
        (SELECT bla from a huge view)
END

確実な方法があるといいですね!

于 2009-05-25T04:58:17.847 に答える
-4

不要なチェックを避けることでパフォーマンスを向上させるために、MS Sql サーバーが短絡理論をサポートしていることは明らかですが、

サポート例:

SELECT 'TEST'
WHERE 1 = 'A'

SELECT 'TEST'
WHERE 1 = 1 OR 1 = 'A'

ここで、最初の例では、「varchar 値 'A' をデータ型 int に変換するときに変換に失敗しました。」というエラーが発生します。

条件 1 = 1 が TRUE と評価されるため、2 番目の条件は簡単に実行されるため、2 番目の条件はまったく実行されません。

さらに

SELECT 'TEST'
WHERE 1 = 0 OR 1 = 'A'

ここでは、最初の条件が false と評価されるため、DBMS は 2 番目の条件に進み、上記の例のように変換エラーが発生します。

注: クエリの結果がエラーである場合、条件が実行または短絡されていることを理解するためだけに誤った条件を書きました。

簡単な説明

検討、

WHERE 1 = 1 OR 2 = 2

最初の条件がTRUEに評価されるため、2 番目の条件を評価しても意味がありません。これは、どの値で評価しても結果にまったく影響しないため、Sql Server が不要な条件チェックまたは評価をスキップしてクエリ実行時間を節約する良い機会です。 .

「OR」の場合、最初の条件がTRUEと評価された場合、 「OR で接続されたチェーン全体が、他の条件を評価せずに真と評価されたと見なされます。

condition1 OR condition2 OR ..... OR conditionN

condition1 が true と評価された場合、conditionN がスキップされるまですべての条件を休止します。最初のTRUEの決定における一般化された言葉では、OR によってリンクされた他のすべての条件はスキップされます。

2番目の条件を検討してください

WHERE 1 = 0 AND 1 = 1

最初の条件がFALSEに評価されているため、2 番目の条件を評価しても意味がありません。これは、どの値で評価しても結果にまったく影響しないため、Sql Server が不要な条件チェックまたは評価をスキップしてクエリ実行時間を節約する良い機会です。 .

「AND」の場合、最初の条件がFALSEと評価された場合、 「AND」に接続されたチェーン全体が他のものを評価せずに FALSE と評価されたと見なされます。

condition1 AND condition2 AND ..... conditionN

condition1 がFALSEと評価された場合、 conditionNがスキップされるまですべての条件を休止します。最初のFALSEの決定で一般化された言葉で言えば、ANDでリンクされた他のすべての条件はスキップされます。

したがって、賢明なプログラマーは常に、費用がかからない、または最も排除する条件が最初に評価されるような方法で一連の条件をプログラムするか、または短絡の最大の利益を得ることができるような方法で条件を調整する必要があります。

于 2015-06-12T07:57:32.887 に答える