|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Оптимизатор настолько оптимален, что иногда решает просто не возвращать строки - ведь так быстрее) Собственно сами запросы и результаты (первый просто показывает что dbms_random.value работает как задумано): Код: 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.
Проверено и воспроизводится на: Oracle Database 18c Standard Edition 2 Release 18.0.0.0.0 Oracle Database 18c Express Edition Release 18.0.0.0.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 Понятно, что можно добавить хинт NO_MERGE или прибить гвоздями Код: plsql 1.
Морали у басни не будет ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 12:22 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Misha111Проверено и воспроизводится на: Oracle Database 18c Standard Edition 2 Release 18.0.0.0.0 Oracle Database 18c Express Edition Release 18.0.0.0.0 Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 Oracle Database 10g Enterprise Edition Release 10.2.0.4.0+ Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 12:32 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Misha111Оптимизатор настолько оптимален, что иногда решает просто не возвращать строки - ведь так быстрее) Ну наступили на багу оптимизатора. Не Вы первый, не Вы последний. По wrong results много смешных багов было. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 13:32 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
andrey_anonymous, до тех пор, пока no_merge и "прибить гвоздями" работает, имхо, это спорный вопрос - баг ли это вообще. Попытка его "исправить", скорее всего, приведет к худшим последствиям. Мне кажется, дешевле считать в списке особенностей, необходимых к учету при работе с псевдостолбцами. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 13:47 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
andrey_anonymousПо wrong results много смешных багов было. и будет) впервые вижу баг wrong results без джоинов и крокодилов, да еще и на dual`е да и не часто их тут выкладывают... ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 14:42 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
boobyбаг ли это вообще.+1 Misha111да еще и на dual`еМногим непонимание dbms_random-а кажется багом. Поначалу. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 15:21 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
booby до тех пор, пока no_merge и "прибить гвоздями" работает, имхо, это спорный вопрос - баг ли это вообще. Да нет - это баг. Нельзя так глубоко проталкивать предикат с ROWNUM внутрь если там есть WHERE clause. Оптимизатор должен понимать что where tst=0 rownum <= 10 и rownum <= 10 а затем where tst=0 совершенно неэквивалентны. SY. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 15:27 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
SY, там rownum <= 10 для красоты тесткейса прикручено. без него работает аналогично вот планы запросов без rownum <= 10 Код: 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.
похоже во втором случае оракл считает что dbms_random.value возвращает одинаковые значения для всех строк и вычисляет random только один раз. это подтверждается если изменить на dbms_random.value(0,5) - примерно каждый пятый запуск будет возвращать результат. вот только подтвердить не могу - при добавления поля tst в верхний селект магия пропадает... Elic, а в чем непонимание dbms_random-а? только не нужно посылать в RTFM и STF. на словах можно? ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 16:07 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Misha111на словахКто изощрённо использует в запросах недетерминированные функции - тот ССЗБ. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 16:22 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Elicboobyбаг ли это вообще.+1 Misha111да еще и на dual`еМногим непонимание dbms_random-а кажется багом. Поначалу.Это вполне конкретный баг связанный с query transformations. Итоговый запрос не эквивалентен изначальному. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13.
Некорректно преобразуется в Код: plsql 1. 2. 3. 4.
В принципе, итоговый текст запроса в трассе 10043 тоже может не оражать действительность, но вот предикаты в плане точно показывают проблему. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 16:52 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
SYbooby до тех пор, пока no_merge и "прибить гвоздями" работает, имхо, это спорный вопрос - баг ли это вообще. Да нет - это баг. Нельзя так глубоко проталкивать предикат с ROWNUM внутрь если там есть WHERE clause. Оптимизатор должен понимать что where tst=0 rownum <= 10 и rownum <= 10 а затем where tst=0 совершенно неэквивалентны. SY. оракля что-то дополнительно (бажно) знает об dbms_random.value если заменить на пользоательскую ф-цию то записи возвращаются, так-же если заменить константы, напр dbms_random.value(rn-rn,200) .... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 16:56 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Misha111впервые вижу баг wrong results без джоинов и крокодилов, да еще и на dual`еБагов с трансформациями запросов и недетерминированными функциями вагон и маленькая тележка. Если сделать в твоем запроса генератор от 0 до 99 через mod + ora_hash + sys_guid вместо dbms_random.value то воспроизводится ещё проще - без всякой аналитики. Код: 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.
Misha111да и не часто их тут выкладывают...Ну вот ещё пример 19464417 . ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 16:59 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
недокопипастил Планы одинаковые Код: 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.
..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 17:05 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Staxоракля что-то дополнительно (бажно) знает об dbms_random.value если заменить на пользоательскую ф-цию то записи возвращаются, так-же если заменить константы, напр dbms_random.value(rn-rn,200)Дело не в dbms_random.value (или как было показано выше mod ora_hash sys_guid), а в недетминированной природе результата. Если предположить, что выражение детерминировано, то трансформации в этом случае эквивалентны. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 17:38 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Кобанчег, імхо если ЯВНО не обьявлено deterministic то ф-цию считать недетминированной поетому такое поведение считаю багом (а не изощренностью) .... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 17:51 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
КобанчегНу вот ещё пример 19464417 . да. там NLK приводит пример с asktoma который еще красивее: Код: plsql 1. 2. 3.
запрос вместо ожидаемых 10% данных возвращает все 100 строк (редко), либо ничего. согласен с Staxоракля что-то дополнительно (бажно) знает об dbms_random.value ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 17:54 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Staxпоетому такое поведение считаю багом (а не изощренностью)Одни считают, а другие не ходят по тонкому льду. ... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 18:11 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Misha111ожидаемыхКто-то ожидает, кто-то (и Том Кайт тоже) нет. Можно принудить функцию в where вызываться на каждую строку как-то так Код: plsql 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
19.09.2019, 18:14 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
SY... Нельзя так глубоко проталкивать предикат с ROWNUM внутрь если там есть WHERE clause. Оптимизатор должен понимать что ... Всё-таки - не уверен. Мне продолжает казаться, что правда где-то между тем, на что намёкивает, но не рассказывает Elic и убежденностью Stax в своей правоте. Вот эта убежденность и является предметом сомнения. Вот балбесья версия: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
1) В списке Select верхнего (назовем первым сверху) уровня присутствует только rn, определенный на самом глубоком (5-ом) уровне запроса. Формально, остальные поля, по возможности, не должны вычисляться вообще. ord, заявленный на втором уровне, в результате не требуется, поэтому может быть целиком выкинут из списка вычисления второго уровня, после чего там остаётся только rn, и становится не видно никаких разумных причин, по которым второй уровень не должен быть целиком выкинут (смержен с третьим). Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
2) Присутствующий на уровне 3 tst не используется на уровнях выше и не должен был бы совсем вычисляться в списке Select 3-го уровня, если бы не потребность использовать его в фильтре 3-го уровня, где он единственный участник. И, так как tst - значение функции, не используемой на вышележащих уровнях, и вычисляемой на 4м уровне, то следующий оптимизирующий ход практически очевиден - надо: а) выкинуть третий уровень целиком (смержить с четвертым), и б) вычисляющую tst функцию целиком переместить из списка Select 4-го уровня в фильтр подзапроса четвертого уровня. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
3) теперь запрос становится неотличим от Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
И весь вопрос остается в том - разумно ли разумное требование Stax по отношению к недетерминированной функции, параметры которой константы и не зависят от источника данных. Пусть даже разумно. Но Том Кайт призывал не делать на сей счет никаких предположений... И результат-то запрос все равно вернет, даже при единственном входе в dbms_random. Просто произойдет это в среднем в одном случае из ста запусков, в соответствии с фильтром. А чтобы предотвратить смерживание, кроме всех прочих вариантов, в этом примере достаточно в верхнем список Select воспользоваться значением ord. Ну, можно еще, в стиле Филиппа Филипповича Преображенского, требовавшего с Петра Александровича настоящую бумажку, требовать с Oracle знания об окончательно, фактически недерминированных функциях, обязанных выполняться в фильтре на каждую строку источника, даже если их вызов не зависит от потока данных и они не используются в списках выбора. Боюсь только, что угроза отъезда из Москвы в Сочи, в данном случае, никого не испугает. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2019, 02:26 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
в целом Elic прав: ElicКто изощрённо использует в запросах недетерминированные функции - тот ССЗБ. Вижу, тут у многих недопонимание, чем отличается операция FILTER от FILTER PREDICATES в других операциях: операция FILTER сначала пытается вычислить все предикаты, которые не зависят от дочерних row sources, и если они заведомо не удовлетворяют, то она даже не будет запускать дочерние операции. вот простой пример с двумя разными фильтрами и фильтр предикатом в дочернем row-source Код: 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.
NULL IS NOT NULL - переписанный 1=0 Staxесли заменить на пользоательскую ф-цию то записи возвращаются да ну? Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2019, 03:56 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
xtenderStaxесли заменить на пользоательскую ф-цию то записи возвращаются да ну? Код: 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.
для такой ф-ции (без dbms_random) можете добится "оптимизации" Код: 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.
..... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2019, 08:47 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Staxдля такой ф-ции (без dbms_random) можете добится "оптимизации" ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2019, 08:52 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
xtender, о кажись понял, был неправ оптимизирует (вызывает раз) .... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2019, 08:57 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Elic, я был неправ насчет Staxоракля что-то дополнительно (бажно) знает об dbms_random.value если заменить на пользоательскую ф-цию то записи возвращаются, зы на неудачной ф-ции попробовал (детермінірованной) .... stax ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2019, 09:01 |
|
Немного магии оптимизатора Оракла
|
|||
---|---|---|---|
#18+
Это же получается? Если один и тот же запрос дает разные результаты с и без использования no_query_transformation, то это перестало быть багом? Теперь и non-deterministic функции в запросах использовать нельзя, а иначе - ССЗБ? Бейте меня ногами, но я не готов принять вашу философию. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.09.2019, 09:48 |
|
|
start [/forum/topic.php?fid=52&msg=39864028&tid=1882057]: |
0ms |
get settings: |
11ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
50ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
66ms |
get tp. blocked users: |
1ms |
others: | 17ms |
total: | 183ms |
0 / 0 |