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, с другой стороны, порядок операций определяется оптимизатором, а не вами, поэтому оптимизаторсвободен от короткого замыкания или нет, как он хочетУ Джонатана Дженника есть отличная статья Subquery Madness! , в которой это обсуждается довольно подробно.В вашем конкретном случае, если у вас есть составной индекс (FIRST_NAME, HIRE_DATE, STATUS) вместе с соответствующей статистикой, оптимизатор почти наверняка будет использовать индекс для оценки первых трех условий, а затем вызовет только функцию CALCULATE_INCENTIVE
для идентификаторов.что соответствует другим трем критериям.Если вы создадите индекс на основе функции в CALCULATE_INCENTIVE(id)
, оптимизатор, скорее всего, будет использовать его, а не вызывать функцию вообще во время выполнения.Но оптимизатор был бы совершенно свободен, чтобы решить вызывать функцию для каждой строки в любом случае, если бы он решил, что это будет более эффективно сделать.