Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

Порядок выполнения условий в блоке WHERE запроса SQL на БД ORACLE

#sql #oracle


Пример SQL запроса

select 1 
  from dual
 where condition1 
    or condition2


В ходе прочтения книги по oracle от Прибыл/Фейрштейн встречал, что ORACLE при отборах
использующих OR действует следующим образом


Если condition1 - TRUE, то осуществляем выборку без проверки condition2
Иначе condition1 - FALSE, то переходим к проверке condtition2


Верно ли это? 

Попытка найти это в книге не дала положительного результата 
    


Ответы

Ответ 1



SQL в общем случае - это декларативный язык. Вы говорите что хотите получить, но не говорите как. СУБД сама решает, как именно получать ваши данные. Например Oracle может(и почти всегда будет) переписывать ваши запросы для построения наиболее оптимального плана. По этому в общем случае вы вообще не можете быть уверены, что ваш запрос будет иметь такой же вид. И практическое применение ваших знаний не зависимо от результат особо не имеет смысл. Однако можно попробовать понять, что происходит с планом запроса для вашего примера. Запрос: select 1 from dual where 1=1 or 1 != 1 План: Plan Hash Value : 1388734953 ----------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | Time | ----------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 2 | 00:00:01 | | 1 | FAST DUAL | | 1 | | 2 | 00:00:01 | ----------------------------------------------------------------- Видим, что Oracle знал заранее что первый аргумент ВСЕГДА True и просто вообще исключил ее из плана запроса. Попробуем чуть усложнить пример: create table tst(id number, text varchar2(10)); insert into tst values(1, null); insert into tst values(2, 'text'); select 1 from tst where id in (1, 2) or text != 'Дядушка Шу' План: Plan Hash Value : 4148258400 --------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | Time | --------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 2 | 40 | 3 | 00:00:01 | | * 1 | TABLE ACCESS FULL | TST | 2 | 40 | 3 | 00:00:01 | --------------------------------------------------------------------- Predicate Information (identified by operation id): ------------------------------------------ * 1 - filter("TEXT"<>'Дядушка Шу' OR "ID"=1 OR "ID"=2) Note ----- - dynamic sampling used for this statement Видим в плане запрос был переписан и условие where теперь больше похоже на where "TEXT"<>'Дядушка Шу' OR "ID"=1 OR "ID"=2 Вывод: Логично предположить, что оптимизация описанная вами используется в Oracle как и во многих ЯП. Однако, не зависимо от того, в каком порядке и как обрабатываются условия в логическом выражении вы не можете на это полагаться для решения практических задач при написании sql, так как вы не управляете планом запроса и итоговый запрос может отличаться от вашего.

Комментариев нет:

Отправить комментарий