powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / DBMS_SQL странное поведение
15 сообщений из 15, страница 1 из 1
DBMS_SQL странное поведение
    #39636840
mrsergej
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго времени суток.

Прошу совета по следующей проблеме: есть представление на основе инмемори таблицы, в представлении также
используются анпивот и группировки. Представление снаружи ограничивается по нескольким полям: по обязательному полю с датой и ещё необязательному типа varchar2. Проблема вылезла очень неожиданным для меня образом: в тексте запроса имеется следующая
конструкция (знакомая апексоводам) -
Код: plsql
1.
2.
WHERE ДК.DOPER = TO_DATE(:P3_DATE, 'DD.MM.YYYY')                           
    AND (:P3_CLI_CODE IS NULL OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')



при использовании DBMS_SQL мой код выполняется примерно 15с, причём если использовать execute immediate c using'ом,
то запрос отрабатывает быстро ~3c. Причём заметил следующее если убрать второе условие или заменить его на
Код: plsql
1.
AND (ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')


то запрос отрабатывает быстро, но если в условии появляется OR, то беда.

Я так понимаю, что 15с. это полный перебор всех значений в столбцах, т.е. условие ДК.DOPER = TO_DATE(:P3_DATE, 'DD.MM.YYYY'),
не применяется. Почему это происходит я понять не могу.

У кого есть идеи по данному поводу?
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39636873
123йй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mrsergejAND (ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')
а вы уверенны, что вам такое надо при условии
ДК.CLI_CODE=12345678
:P3_CLI_CODE=5
?
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39637103
mrsergej
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
123ййmrsergejAND (ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')
а вы уверенны, что вам такое надо при условии
ДК.CLI_CODE=12345678
:P3_CLI_CODE=5
?

Не очень понял, честно говоря о чём был вопрос.

У кого какие идеи? Очень странно, что запрос ведёт себя таким образом именно при использовании DBMS_SQL.
Хотя бы подскажите в какую сторону нужно копать.
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39637108
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mrsergejЯ так понимаю, что 15с. это полныйТо есть ты не в состоянии посмотреть актуальные планы выполнения?
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39637144
mrsergej
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ElicmrsergejЯ так понимаю, что 15с. это полныйТо есть ты не в состоянии посмотреть актуальные планы выполнения?

15с это полный перебор.
Т.к. таблица inmemory, то в плане всегда присутствует TABLE ACCESS INMEMORY FULL (план всегда одинаковый), но при выполнении
запроса просто в sql окне или через execute immediate с секцией using запрос отрабатывает быстро.

Я так понимаю, что это связано с bind переменными в запросе, а не с наличием OR как я предполагал ранее, т.к. заметил следующую
особенность: если использовать вместо bind переменной литерал, то даже с OR запрос отрабатывает быстро, т.е. вместо
Код: plsql
1.
AND (:P3_CLI_CODE IS NULL OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')


использовать
Код: plsql
1.
AND (1=2 OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')


или
Код: plsql
1.
AND (1=1 OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639263
mrsergej
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может есть ещё идеи в какую сторону копать?
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639279
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mrsergejМожет есть ещё идеи в какую сторону копать?

Копайте в сторону Австралии

и вообще задумайтесь в чем сокральный смысл такой конструкции
Код: plsql
1.
AND (:P3_CLI_CODE IS NULL OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')



если при :P3_CLI_CODE = null выберутся все значения по условию :P3_CLI_CODE IS NULL и по условию ДК.CLI_CODE LIKE '%' || null || '%'
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639298
mrsergej
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MaximaXXLmrsergejМожет есть ещё идеи в какую сторону копать?

Копайте в сторону Австралии

и вообще задумайтесь в чем сокральный смысл такой конструкции
Код: plsql
1.
AND (:P3_CLI_CODE IS NULL OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')



если при :P3_CLI_CODE = null выберутся все значения по условию :P3_CLI_CODE IS NULL и по условию ДК.CLI_CODE LIKE '%' || null || '%'

Я сейчас только для Вас открою тайну, можете записать куда-нибудь, чтобы не забыть - при значении :P3_CLI_CODE = null второе условие проверяться даже и не будет
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639310
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
IMHO & AFAIK 1
Может выполнятся и не будет, но план портить вполне может....
(т.к. оптимизитор в момент парсинга об этом факте может и не знать)

IMHO 2
Ну и вообще, если есть разница в выполнении. то первым делом желательно сравнить планы.
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639329
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mrsergejЯ сейчас только для Вас открою тайну, можете записать куда-нибудь, чтобы не забыть - при значении :P3_CLI_CODE = null второе условие проверяться даже и не будет


Ой не надо мне открывать страшных тайн, а то я даже не уверен что являеться вторым условием для Оракла
Единственное что не выберется по условию ДК.CLI_CODE LIKE '%' ||null|| '%' это ДК.CLI_CODE равное null и если у Вас поле "is not null" то как Вы сами и писали "примерно 15с ... быстро ~3c"
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639341
mrsergej
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Leonid KudryavtsevIMHO & AFAIK 1
Может выполнятся и не будет, но план портить вполне может....
(т.к. оптимизитор в момент парсинга об этом факте может и не знать)

IMHO 2
Ну и вообще, если есть разница в выполнении. то первым делом желательно сравнить планы.

У меня тоже складывается ощущение, что когда оптимизатор на момент парсинга понимает результат в левой части условия
(:P3_CLI_CODE IS NULL OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%'),
то и результат я получаю тот, который ожидаю, но при использовании переменных он не знает, что там будет - истина или ложь и
как его заставить использовать обязательное условие (ДК.DOPER = TO_DATE(:P3_DATE, 'DD.MM.YYYY')) при таком варианте не понятно.

По поводу планов, я не большой спец в инмемори таблицах, но у меня всегда при использовании этой таблицы одинаковый план.
Я не понимаю, почему обязательное условие ДК.DOPER = TO_DATE(:P3_DATE, 'DD.MM.YYYY') применяется не всегда.
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639373
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AFAIK по sql_id можно из представлений вытащить реальные планы выполнения

Я делал просто:
добавлял в запросы какой нибудь комментарий (что бы они отличались), потом по v$sql находил нужный запрос, в v$sql_plan соответственно реальный план, в v$sql_bind???? вроде можно посмотреть реальное значение bind переменных

Наверное можно добавить хинты, что бы бы планы совпали IMHO

p.s. надеюсь в представлениях не ошибся, при написание ответа не проверял
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39639433
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid KudryavtsevAFAIK по sql_id можно из представлений вытащить реальные планы выполнения
Первая разумная мысль в данном топике.
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39641634
Руслан Дамирович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переписать
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
AND (:P3_CLI_CODE IS NULL OR ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%')
--1:
AND 1 = CASE 
  WHEN :P3_CLI_CODE IS NULL THEN 1 
  WHEN ДК.CLI_CODE LIKE '%' || :P3_CLI_CODE || '%' THEN 1
END
--2:
AND ДК.CLI_CODE LIKE '%' || NVL( :P3_CLI_CODE, '' ) || '%' 
...
Рейтинг: 0 / 0
DBMS_SQL странное поведение
    #39641969
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руслан Дамирович,

Ваш второй вариант справедлив только для случая если поле ДК.CLI_CODE не имеет значений null
Код: plsql
1.
2.
--2:
AND ДК.CLI_CODE LIKE '%' || NVL( :P3_CLI_CODE, '' ) || '%' 



пример
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
with t as (select 1    CLI_CODE from dual union all
           select null CLI_CODE from dual)
select *
from t
where CLI_CODE LIKE '%' || NVL( null, '' ) || '%' 

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


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