8

2番目のテーブルからデータをクエリする必要がありますが、プライマリテーブルのまれな条件のセットが満たされた場合に限ります。

SELECT ..., IF(a AND b AND c AND (SELECT 1 FROM tableb ...)) FROM tablea ...

a、b、およびcの条件はほとんどの場合偽であるため、私の考えでは、サブクエリは結果セットのほとんどの行に対して実行されることはなく、したがって結合よりもはるかに高速です。しかし、それはIF()ステートメントが短絡した場合にのみ当てはまります。

しますか?

あなたたちが提供できるどんな助けにも感謝します。

4

4 に答える 4

10

答えはイエスです。
mysqlクエリ内のIF(cond、expr_true、expr_false)が短絡しています。

ここでは、@variablesを使用して事実を証明するテストを行います。

SET @var:=5;  
SELECT IF(1 = 0, (@var:=@var + 1), @var ); -- using ':=' operator to modify 'true' expr @var 
SELECT IF(1 = 1, @var, (@var:=@var + 1) ); -- using ':=' operator to modify 'false' expr @var 
SELECT @var;

結果は、3つのSELECTクエリすべてから「5」になります。

IF()関数が短絡していない場合、結果はSELECT#1から「5」、SELECT#2から「6」、最後の「select@var」から「7」になります。

これは、select#1では「true」式が実行されないためであり、select#2ではfalse式も実行されないためです。

':='演算子は、SQLクエリ(select、from、およびwhere句)内で@varを変更するために使用されることに注意してください。これから、本当に凝った/複雑なSQLを取得できます。@varsを使用して、SQLクエリ内に「手続き型」ロジックを適用しました。

--J Jorgenson-

于 2010-09-21T18:50:37.030 に答える
2

J. Jorgensonの助けを借りて、私は自分のテストケースを思いついた。彼の例では、条件評価で短絡を試みていませんが、彼のアイデアを使用して、独自のテストを考え出し、MySQLが実際にIF()条件チェックを短絡することを確認しました。

SET @var:=5;
SELECT IF(1 = 0 AND (@var:=10), 123, @var); #Expected output: 5
SELECT IF(1 = 1 AND (@var:=10), @var, 123); #Expected output: 10

2番目の例では、MySQLが適切に短絡しています。@varが10に設定されることはありません。

J. Jorgensonの助けに感謝します!

于 2010-09-22T13:56:01.197 に答える
0

SQLアナライザーで試してみてください。安全を確保し、データベースが一方向に機能することを信頼する必要がない場合(そして、新しいバージョンでその動作を変更しない場合)は、2つのクエリを実行し、プログラムでIFを実行します。

于 2010-09-14T21:38:39.257 に答える
0

場合によります。

IFは、GROUP_CONCATによる切り捨て警告を回避するために使用できるように短絡しません。たとえば、次のようになります。

set @@group_concat_max_len = 5;

select if(true or @var:=group_concat('warns if evaluated'), 'actual result', @var);

結果は「実際の結果」になりますが、警告が表示されます。

Warning (Code 1260): Row 1 was cut by GROUP_CONCAT()

これは、個別のキーなど、些細なGROUP_CONCAT式を使用した場合や、IFをまったく使用しない場合に発生する警告と同じです。

于 2014-07-24T23:38:54.430 に答える