Oracle は、PL/SQL での短絡評価をサポートしています。ただし、SQL では、オプティマイザーは自由に述語を任意の順序で評価したり、述語をビューやサブクエリにプッシュしたり、SQL ステートメントを必要に応じて変換したりできます。これは、述語が特定の順序で適用されることに依存してはならないことを意味し、順序述語が WHERE 句に現れるのは本質的に無関係になります。使用可能なインデックス、存在するオプティマイザ統計、オプティマイザ パラメータ、およびシステム統計はすべて、WHERE 句の述語の順序よりもはるかに重要です。
たとえば、PL/SQL では、実際に呼び出された場合にエラーをスローする関数を使用して、これを実証できます。
SQL> ed
Wrote file afiedt.buf
1 create function throw_error( p_parameter IN NUMBER )
2 return number
3 as
4 begin
5 raise_application_error( -20001, 'The function was called' );
6 return 1;
7* end;
SQL> /
Function created.
SQL> ed
Wrote file afiedt.buf
1 declare
2 l_num NUMBER;
3 begin
4 l_num := 1;
5 if( l_num = 2 and throw_error( l_num ) = 2 )
6 then
7 null;
8 else
9 dbms_output.put_line( 'Short-circuited the AND' );
10 end if;
11 if( l_num = 1 or throw_error( l_num ) = 2 )
12 then
13 dbms_output.put_line( 'Short-circuited the OR' );
14 end if;
15* end;
16 /
Short-circuited the AND
Short-circuited the OR
PL/SQL procedure successfully completed.
一方、SQL では、操作の順序はユーザーではなくオプティマイザーによって決定されるため、オプティマイザーは自由に短絡することも短絡しないこともできます。Jonathan Gennick は Subquery Madness というすばらしい記事を書いています。これについて詳しく説明しています。あなたの特定のケースでは、(FIRST_NAME, HIRE_DATE, STATUS) に適切な統計とともに複合インデックスがある場合、オプティマイザーはほぼ確実にインデックスを使用して最初の 3 つの条件を評価し、次に一致CALCULATE_INCENTIVE
した ID の関数のみを呼び出します。他の3つの基準。関数ベースのインデックスを作成した場合CALCULATE_INCENTIVE(id)
、オプティマイザーは、実行時に関数をまったく呼び出すのではなく、それを使用する可能性があります。ただし、オプティマイザは、どちらの場合でも、その方が効率的であると判断した場合、すべての行に対して関数を呼び出すことを完全に自由に決定できます。