|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Нашел баг в оракле 11.2. Похоже что в оптимизаторе. Код: plsql 1. 2. 3. 4. 5. 6. 7.
Внутренний селект пустой, (doc_type_id всегда положителен). Внешний селект умудряется потрогать строчку в пустой таблице, как видно по распечатке. Баг достаточно хрупкий, если попытаться узнать номер строчки или любые другие ее атрибуты, баг пропадает. На маленьких таблицах тоже не случается, нужны тысячи строчек. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 00:39 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
это не баг, для этого есть другой термин - "трансформация запроса". Система считает себя вправе преобразовать твой запрос к виду Код: plsql 1. 2. 3. 4. 5. 6.
(Возможно, именно об этом думал Elic, высказывая сомнение в полезности раннего знания о флаге deterministic.) А вообще, скажи системе, что тебе этого не надо, превратив инлайн вью в non mergeable, или явно запрети ей попытки трансформации соответствующим хинтом. на будущее - порядок выполнения функции и количество ее вызовов в запросе официально не определяется, никак, хотя известны случаи устойчивого поведения, на которые можно более-менее положиться. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 02:16 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
кстати, тебе нравятся запросы сорта Select * From ( Select function(someparam) as p From table ) t Order by p Так вот, строго говоря, никаких обещаний по количеству раз, которое будет вызвана function Oracle принципально не дает, оставляя за собой право вычислять ее столько раз, сколько ему понадобится в процессе сортировки, кроме некоторых, официально не оговорённых, но на практике известных случаев. Работа с функцией в запросе, и особенно пользовательской, это всегда счастье и гордость от быстрого и умелого освоения инструмента. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 02:35 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
booby это не баг, для этого есть другой термин - "трансформация запроса". Система считает себя вправе преобразовать твой запрос .. А вообще, скажи системе, что тебе этого не надо, превратив инлайн вью в non mergeable, или явно запрети ей попытки трансформации соответствующим хинтом. Это интересно, я наивно полагал что скобки определяют порядок операций, и после внутренней пустышки дело дальше не пойдет, а оказывается это вовсе не так и скобки контролируют не это. То, что в самом WHERE порядок вычисления (не порядок эвалюации) условий произвольный и непредсказуемый, я уже прочитал. Я попробовал преобразованный пример из твоего ответа - функция вызывается, из условия WHERE, как и ожидалось (я там поменял текст). Т.е. оптимизатор посчитал нужным вызвать недерминистическую функцию до того, как сравнивать простые числа. Код: plsql 1. 2. 3. 4. 5. 6.
Хотя, если попросить распечатать атрибут (закомментированый выше), то оптимизатор меняет свое мнение и больше функцию не вызывает. Или на маленьких таблицах. Или на больших новых таблицах. Возможно, оптимизатор убежден, что читать поле doc_type_id из уже известной строчки слишком дорого. По поводу вызывания функций в селекте - так ведь виртуальные колонки так и работают. Я выбрал функцию с заметным побочным эффектом потому что мне интересно как оптимизатор работает. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 03:58 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Про детерминистик: http://orasql.org/category/oracle/deterministic-functions/ Про вызов функций: http://orasql.org/2013/06/10/too-many-function-executions/ ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 04:52 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
booby (Возможно, именно об этом думал Elic, высказывая сомнение в полезности раннего знания о флаге deterministic.) . ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 04:55 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
НеофитSQL Возможно, оптимизатор убежден Ну так посмотри план выполнения. Предположу, что он другой для запроса с doc_type_id, т.к. при наличии индекса на doc_id в первом случае фильтр по функции не требует извлечения строки таблицы. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 09:35 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
НеофитSQL Или на маленьких таблицах. Или на больших новых таблицах. Фазы Луны и положение Меркурия в Скорпионе забыли. Начните уже читать документацию и литературу по теме. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 09:39 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
booby это не баг , для этого есть другой термин - "трансформация запроса". Система считает себя вправе преобразовать твой запрос к виду Код: plsql 1. 2. 3. 4. 5. 6.
(Возможно, именно об этом думал Elic, высказывая сомнение в полезности раннего знания о флаге deterministic.) А вообще, скажи системе, что тебе этого не надо, превратив инлайн вью в non mergeable, или явно запрети ей попытки трансформации соответствующим хинтом. на будущее - порядок выполнения функции и количество ее вызовов в запросе официально не определяется, никак, хотя известны случаи устойчивого поведения, на которые можно более-менее положиться. почему не баг? ф-ция хоч 100 раз пусть вызывается doc_type_id всегда положителен , строки не должны возвращатся при and t.doc_type_id < 0 ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 09:57 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Stax, Так они и не вернулись. Всё в порядке. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 10:53 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
booby Stax, Так они и не вернулись. Всё в порядке. он что руками набрал? BUG -------------------------------------------------------------------------------- error 50128384 ps запутался я ...... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 11:32 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Stax, Первый ответ в теме. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 11:46 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Без трейса 10053 или хотя бы планов, нет никакого смысла это обсуждать. Тем более непонятно на какой версии 11.2.?.? ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 11:48 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
env Stax, Первый ответ в теме. я понимаю что ф-ция может вызываться (как и показано), но селект полюбому не должен возвращать строку BUG -------------------------------------------------------------------------------- error 50128384 ps no rows selected / "пусто", но не строку ..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 12:17 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Стас, скорее всего тут no rows selected + аутпут функции фпринт. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 12:42 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
env, Ага, скорее всего, тупо feedback выключен ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 12:50 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
xtender env, Ага, скорее всего, тупо feedback выключен имхо шапочку не введет BUG -------------------------------------------------------------------------------- ...... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 12:58 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Stax, "error 50128384" это был результат output. Строчек вернулось ноль, как и ожидалось. Со счетчиком было бы понятнее. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9.
План показывает такой (удалил пустые столбцы). Надеюсь когда-нибудь научиться читать такие вещи. Жаль, что функцию не упоминает. Код: plaintext 1. 2. 3. 4. 5.
... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 17:42 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
НеофитSQL, 1. еще раз смотри сообщение выше: 22199705 2. RULE - нахрена? 3. планы надо показывать нормально через dbms_xplan со всеми нужными секциями. Если не знаешь какие, показывай с параметром 'advanced'. 4. в выводе dbms_xplan есть секция projections, по ней видно на какой строке плана он ее вызывает. 5. не надо переформатировать вывод из sqlplus. В данном случае ты буквально всех обманул в стартовом посте ложным выводом. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 18:02 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
xtender НеофитSQL, 1. еще раз смотри сообщение выше: 22199705 2. RULE - нахрена? 3. планы надо показывать нормально через dbms_xplan со всеми нужными секциями. Если не знаешь какие, показывай с параметром 'advanced'. 4. в выводе dbms_xplan есть секция projections, по ней видно на какой строке плана он ее вызывает. 5. не надо переформатировать вывод из sqlplus. В данном случае ты буквально всех обманул в стартовом посте ложным выводом. 1. Да, я прочитал. Как уже видно из текста, я не знал об оптимизации merge раскрывающий подчиненный селект. 2. Это один из хинтов, с которыми я экспериментировал. 3. Гуглю dbms_xplan. Благодарю за наводку. .. 5. Взял с экрана как есть, ничего не редактировал. Было бы удобнее если бы мой PL/SQL Developer показывал <empty result set> или что-то подобное, чтоб народ на форуме не обманывать. Наверное в следующий раз от руки напишу, будет вот так: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 19:56 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Поигрался еще. Добавил "no merge" во внутренний селект, а потом уже везде где можно. План поменялся (т.е. "no merge" был замечен), но поведение осталось прежним - продолжает печатать на экран. Код: plsql 1. 2. 3. 4.
Переделал как инлайн-вью. Ничего не поменялось, печатает (ожидаемо) Код: plsql 1. 2. 3. 4.
Остается вопрос, как оптимизатор заключил что вызов функции дешевле, чем фетч одного числа по известному ROWID. Функция явно тяжеловесная даже на вид, требует перехода в другой контекст, и т.д. Этот опыт хорошо доносит идею, что "view" это далеко не резалт сет, а только рецепт как его получить. И даже если вью само по себе пустое (всегда возвращает ноль строчек), это еще не гарантия что к полям несуществующих строчек этого вью кто-то снаружи не дотронется. ... |
|||
:
Нравится:
Не нравится:
|
|||
18.09.2020, 23:35 |
|
Потрогать пустой result set
|
|||
---|---|---|---|
#18+
Может, вернется Booby и пояснит, почему запрет 22199697 на merge optimization не повлиял на поведение. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2020, 01:35 |
|
|
start [/forum/topic.php?fid=52&fpage=36&tid=1880880]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
43ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
others: | 11ms |
total: | 153ms |
0 / 0 |