Гость
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Предикат по короткому условию / 13 сообщений из 13, страница 1 из 1
16.02.2022, 21:10
    #40134651
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
Доброго дня господа !

Имею запрос

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                   ) 



Можно ли дать указание запросу работать по короткому условию констант (T1.F1=1) если это условие истинно,
не обращаться к таблице T2
И как это проверить

Спасибо !

Мысль такая
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                       and T1.F1<>1
                       and T1.F2<>2
                   ) 
...
Рейтинг: 0 / 0
16.02.2022, 21:38
    #40134656
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
HOME_X

Можно ли дать указание запросу работать по короткому условию констант (T1.F1=1) если это условие истинно,
не обращаться к таблице T2
И как это проверить


CASE:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
SELECT  * 
  FROM  T1
  WHERE 1 = CASE
              WHEN T1.F1 = 1 THEN 1
              WHEN T1.F2 = 2 THEN 1
              ELSE (
                    SELECT  1
                      FROM T2
                      WHERE T2.F1 = T1.F3
                        AND ROWNUM = 1 
                    )
            END
/




как это проверить:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
SQL> CREATE TABLE T1
  2    AS
  3      SELECT  1 F1,
  4              1 F2,
  5              1 F3
  6        FROM  DUAL
  7  /

Table created.

SQL> CREATE TABLE T2(F1 NUMBER)
  2  /

Table created.

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1 / 0
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /

        F1         F2         F3
---------- ---------- ----------
         1          1          1

SQL> INSERT INTO T1 VALUES(2,2,2)
  2  /

1 row created.

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1 / 0
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /
ERROR:
ORA-01476: divisor is equal to zero



no rows selected

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /

        F1         F2         F3
---------- ---------- ----------
         1          1          1
         2          2          2

SQL> INSERT INTO T1 VALUES(3,3,3);

1 row created.

SQL> INSERT INTO T2 VALUES(3);

1 row created.

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1
  6                ELSE (
  7                      SELECT  1 / 0
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /
ERROR:
ORA-01476: divisor is equal to zero



no rows selected

SQL> SELECT  *
  2    FROM  T1
  3    WHERE 1 = CASE
  4                WHEN T1.F1 = 1 THEN 1
  5                WHEN T1.F2 = 2 THEN 1
  6                ELSE (
  7                      SELECT  1
  8                        FROM T2
  9                        WHERE T2.F1 = T1.F3
 10                          AND ROWNUM = 1
 11                      )
 12              END
 13  /

        F1         F2         F3
---------- ---------- ----------
         1          1          1
         2          2          2
         3          3          3

SQL>



SY.
...
Рейтинг: 0 / 0
16.02.2022, 22:14
    #40134666
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
SY,

Понял Вас !

Надеялся увидеть параметры настройки базы на манер Hint-ов
У Delphi есть аналогичное - анализ короткой или полной логики условия

Но так тоже подойдет !
Спасибо
...
Рейтинг: 0 / 0
16.02.2022, 22:41
    #40134669
ASNexus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
HOME_X
Доброго дня господа !

Имею запрос

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                   ) 


Можно ли дать указание запросу работать по короткому условию констант (T1.F1=1) если это условие истинно,
не обращаться к таблице T2
И как это проверить

Этот запрос будет выполняться именно так, как Вам нужно: в первую очередь производится проверка условий, в которых сравнение с константами, в т.ч. IS [NOT] NULL, потом уже выполнение подзапросов, вызовы функций и т.п. Независимо от порядка этих условий в WHERE.
Где это прочитать в доке - так с ходу не вспомню. Проверить можно примерами на разных исходных данных, вроде тех, что SY ниже написал.
...
Рейтинг: 0 / 0
16.02.2022, 22:52
    #40134671
ASNexus
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
Кстати, MSSQL в подзапросах [NOT] EXISTS игнорирует всё, что перечислено в его SELECT (может быть это регулируется параметрами - тут не скажу, не знаю), т.е. можно написать что-то вроде "where exists (select 1/0 from ...)" и это не вызовет ошибку "divisor is equal to zero". Возможно Oracle в какой-то версии это тоже сделает (или уже сделал). Исходя из этого, я бы для проверки того, выполняется подзапрос или нет добавил бы условие в WHERE подзапроса, что-то вроде "and T2.F1 / 0 > 0"
...
Рейтинг: 0 / 0
16.02.2022, 23:47
    #40134680
SQL*Plus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
ASNexus
Кстати, MSSQL в подзапросах [NOT] EXISTS игнорирует всё, что перечислено в его SELECT
(может быть это регулируется параметрами - тут не скажу, не знаю),
т.е. можно написать что-то вроде "where exists (select 1/0 from ...)" и это не вызовет ошибку "divisor is equal to zero".

Возможно Oracle в какой-то версии это тоже сделает (или уже сделал).
Исходя из этого, я бы для проверки того, выполняется подзапрос или нет
добавил бы условие в WHERE подзапроса, что-то вроде "and T2.F1 / 0 > 0"


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
SQL> SELECT banner_full FROM v$version;

BANNER_FULL                                                                                                                                                     
-------------------------------------------------------------------------------
Oracle Database 21c Enterprise Edition Release 21.0.0.0.0 - Production
Version 21.4.0.0.0

SQL> SELECT D.department_id, D.department_name 
  2  FROM departments D
  3  WHERE NOT EXISTS (SELECT 1/0 FROM employees E 
  4                    WHERE D.department_id = E.department_id)
  5    AND ROWNUM <= 3;

DEPARTMENT_ID DEPARTMENT_NAME               
------------- ------------------------------
          120 Treasury                      
          130 Corporate Tax                 
          140 Control And Credit  


Предполагаю, что в предыдущих версиях Oracle Database было такое же поведение,
поскольку не имеет значения, что будет в списке выборки кореллированного подзапроса.

Лично я обычно там ставлю * (звездочку).
...
Рейтинг: 0 / 0
17.02.2022, 01:30
    #40134691
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
ASNexus
Кстати, MSSQL в подзапросах [NOT] EXISTS игнорирует всё, что перечислено в его SELECT
Oracle тоже.
ASNexus
"where exists (select 1/0 from ...)" и это не вызовет ошибку "divisor is equal to zero"
смотрите внимательнее, там где ошибка, там было не exists, а просто скалярный подзапрос.
ASNexus
я бы для проверки того, выполняется подзапрос или нет добавил бы условие в WHERE подзапроса, что-то вроде "and T2.F1 / 0 > 0"
вообще это не очень хороший способ проверять, что выполняется...
...
Рейтинг: 0 / 0
17.02.2022, 21:31
    #40134969
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
Sayan Malakshinov,

В качестве проверки использовал поль. функцию , в которую передаю
уникальное значение записи и это значение выводиться в консоль

В целом процесс отслеживается

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                        and MyFunc(T1.F3)=1
                   ) 



ASNexus
Насчет последовательности - Вы правы - первично идут константы.
Ссылка на таблицу в последную очередь

Спасибо
...
Рейтинг: 0 / 0
21.02.2022, 00:08
    #40135441
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
HOME_X,

когда вы добавили and MyFunc(T1.F3)=1
то получили совершенно другой запрос
...
Рейтинг: 0 / 0
21.02.2022, 00:08
    #40135442
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
HOME_X
Насчет последовательности - Вы правы - первично идут константы.
Ссылка на таблицу в последную очередь
а какие индексы у вас есть?
...
Рейтинг: 0 / 0
21.02.2022, 10:59
    #40135540
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
HOME_X

В качестве проверки использовал поль. функцию

если T2.F1=T1.F3 == FALSE, то ф-цию можно и не вызывать

.....
stax
...
Рейтинг: 0 / 0
21.02.2022, 17:35
    #40135704
Sayan Malakshinov
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
HOME_X
Sayan Malakshinov,

В качестве проверки использовал поль. функцию , в которую передаю
уникальное значение записи и это значение выводиться в консоль

В целом процесс отслеживается

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
select * 
   from T1
 where T1.F1=1
      or  T1.F2=2
      or  Exists(select 1 
                      from T2
                    where T2.F1=T1.F3 
                        and MyFunc(T1.F3)=1
                   ) 

введение в запрос функций может заблокировать трансформации. Например, может быть заблокирован join/subquery elimination при FK - тогда без функции подзапрос бы не выполнялся, а из-за добавления функции ораклу придется его выполнять
...
Рейтинг: 0 / 0
21.02.2022, 23:33
    #40135752
HOME_X
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предикат по короткому условию
Sayan Malakshinov

введение в запрос функций может заблокировать трансформации. Например, может быть заблокирован join/subquery elimination при FK - тогда без функции подзапрос бы не выполнялся, а из-за добавления функции ораклу придется его выполнять


преследовал цель - отследить последовательность выполнения кода.
Получил вполне ожидаемый результат - в продуктиве такого не будет
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Предикат по короткому условию / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]