|
|
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
Всем привет. Есть Oracle 11.2.0.4 и такая упрощенная версия запроса Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. подскажите пожалуйста как с помощью хинтов добиться чтобы окакл делал такой план: HASH_JOIN ( NESTED_LOOP(a, c1, ct1), NESTED_LOOP(a, c2, ct2) ) Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 17:29 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76 подскажите пожалуйста как с помощью хинтов добиться чтобы окакл делал такой план Переписать запрос не предлагать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 17:48 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
MaximaXXL, Тоже было бы интересно. Но вопрос с хинтами не снимается. Хочу научиться задавать хинтами такой порядок джойна. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 18:12 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76Хочу научиться задавать хинтами такой порядок джойна.Насколько мне, дилетанту, известно, в существующих версиях оракла ты никогда не получишь nested loops(a, c1) и nested loops(a, c2) в таком вариант запроса. Как говорится, хинтуй - не хинтуй, все равно получишь ... сам знаешь что. Поэтому, прежде чем соваться с хинтами, я бы переписал запрос без скаляра и избыточных джойнов, заменив их группировкой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 18:21 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76, Ну первое что напрашивается - написать одним запросом ... ввести account в единый запрос Второе вынести пару c2 и ct2 в exists Далее, надо вникнуть в логику данных ... очень похоже что можно переписать не используя c2, ct2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 18:28 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
AmKad, скальярный подзапрос это часть довольно большой и сложной вьюшки, по которой раняться разные запросы. Если мы избавимся от скаляра, то будут проблемы с пушеньем предикатов внутрь группировки с вероятностью 99%. ( Оракл будет стараться фулсканить таблицы которые группирует, а это будет еще хуже чем есть ). А мне нужно прочитать C1, Ct1 по индексу и c2, ct2 по индексу. А результаты соединить уже хешем. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 19:25 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76AmKad, скальярный подзапрос это часть довольно большой и сложной вьюшки, по которой раняться разные запросы. Если мы избавимся от скаляра, то будут проблемы с пушеньем предикатов внутрь группировки с вероятностью 99%. ( Оракл будет стараться фулсканить таблицы которые группирует, а это будет еще хуже чем есть ). А мне нужно прочитать C1, Ct1 по индексу и c2, ct2 по индексу. А результаты соединить уже хешем. 1. Хинтом можно запретить пуш предикатов. 2. Тюнить запросы хинтами - должно рассматриваться как самый последний аргумент, если только нет другого выхода. Почему Оракл в данном конкретном случае сам не выбирает правильный план? Статистика лажовая? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 19:40 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
MaximaXXL, Не все понял с Вашего совета, уловил мысль с экзистом. Получил такой вот запрос: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Но он ничего не решает. У нас на одно значение С1.account_number могут быть сотни c1.client_id, аналогично для С2.account_number могут быть сотни c2.client_id. Поэтому как не крути получается план который все четыре таблицы C1, CT1, C2, CT2 джойнить NESTED_LOOPом. Что приводит к замножению строк. Суть запроса примерно такая: Ищутся два типа транзакций ct2.dc_type_id = 5 и ct1.dc_type_id = 4 у различных CLIENT_ID в рамках одного ACCOUNT_NUMBER. И поскольку разных CLIENT_ID может быть довольно много, то получается замножение строк. вот как это выглядит на плане: Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 19:56 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76, Иногда, чтобы сделать одно заключение на множестве строк, необязательно делать джойны. Читай - exists - тот же джойн. Некоторые порядочные люди используют для этого агрегацию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:06 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76, Это просто праздник какой-то..... Ты правда считаешь, что проблема замножения строк кроется в выбранном способе соединения таблиц? Ты серьёзно думаешь, что в случае с hash join-ом результат не будет « Замножаться». Ну или объясни, что ты имеешь ввиду под этим «термином» ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:11 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
Valergrad, 1. Мне наоборот нужно пушить и читать по индексу. 2. Статистика свежая но данные сильно не однородные. У большинства строк на account_number одна строка client_id, но есть такие аккаунты где может быть для одного account_number сотни client_id. В качестве эксперемента ручками уменьшить distinct_value для client.account_number в 100 раз, глянуть какой план получиться. Поменялся порядок джойнов на более удачный, но желаемого плана пока нет: Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:22 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76эксперементаА как правильно? Эксперимент или экскремент? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:26 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
Добрый Э - Эх, да, согласен. Замножение есть хоть в любом случае. Но в том плане, который я хочу - промежуточные результаты строк соединения таблиц будут минимальными, соответсвенно и самый быстрый план. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:31 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76соответсвенно и самый быстрый план.М-м-м, какие мы самоуверенные! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:35 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
AmKad, Виноват, Эксперимент . У меня правильнописание хромает. Оно хорошее, но почему-то хромает. (с) :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:36 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76AmKad, Виноват, Эксперимент . У меня правильнописание хромает. Оно хорошее, но почему-то хромает. (с) :(Да ладно, не заморачивайся. Ошибки правописания - не самые серьезные ошибки в нашей жизни. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 20:38 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76, А на досуг тебе задачка для размышления. Есть две сущности: классы и ученики. Вывести все классы, в которых есть хотя бы по одному Ивану и Владимиру, но нет ни одного Дениса и Вадима. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 21:36 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76, Первое и главное что надо понять для твоего случая - компоненты оптимизатора. About Optimizer Components На русском языке это означает, что сначала выполняются трансформации, потом генерируются планы. В реальной жизни все сложнее, особенно в 12с, но для простоты можно считать так. Если мы хотим два результата NL соединить потом как HASH, то создадим две дополнительные inline view. Код: 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. Что мы имеем? Все по прежнему. Теперь отключим view merging. Код: 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. Я надеюсь есть понимание, что не смотря на соединение по трем предикатам, хеш строится только по тому, где равенство. PS. Потрудись в след раз проявить уважение к помогающим и предоставить скрипты для таблиц и индексов. Мне пришло потратить почти 10 минут чтоб родить сие. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.12.2017, 21:43 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
dbms_photoshop, Спасибо за глубокий и развернутый ответ, прошу извинения за то что не выложил код, обещаю исправиться. 1. Вы наверное олаживали свой запрос на ORACLE 12? т.к. на 11.2.0.4 я получил ошибку: ORA-00904 "A"."ACCOUNT_NUMBER": invalid identifier Из прочитаного по вашей ссылке, делаю вывод что 11ка не умеет делать такую трансформацию, которую я хочу, поэтому и план не получиться такой получить. Правильно? 2. По воводу почему хочу получить такой план. На глаз показалось что это самый быстрый вариант джойна c1, ct1, c2, ct2. Сделал выборку Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Да, признаю. Вариант (мой второй трейс) будет лучше. 3. Вижу, что AmKad знает, как сделать запрос с группировкой, но пока не могу сообразить как. Не очень тренерован в sql. я так понял, что задумка выбрать сразу строки 4,5 типов , и дальше агрегируя получить нужный результат. Написал это, а дальше сообразить не могу: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. Можете кинуть Ваше решение, аналогичный пример, или хотя бы наводящие подсказки? Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 13:55 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76, Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 14:19 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76делаю вывод что 11ка не умеет делать такую трансформациюДело не в трансформации, а в видимости в скаляре всего на один уровень в 11. Можно обойти если сильно захотеть. niv76Можете кинуть Ваше решение, аналогичный пример, или хотя бы наводящие подсказки?Полагаю AmKad намекает, что от semi join можно уйти если написать хитрое выражение в having + decode. И это таки возможно. Начни с задачки 21070947 . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 14:26 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopИ это таки возможно.Из-за self join по неравенству думаю, что нет. Так что не заморачивайся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 15:12 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
1. в задачку кажись решил, и да, применительно к моему примеру сложно применить из-за предикатов на неравенство : Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 2. dbms_photoshop , заинтересовала ваша фраза: Код: plsql 1. Можете для моего примера написать, как это можно обойти? Для поднятия общей образованности. Сам придумать не могу. Спасибо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 19:00 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopdbms_photoshopИ это таки возможно.Из-за self join по неравенству думаю, что нет. Так что не заморачивайся.Рано сдаешься. Равенства по номеру счета должно хватить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 20:49 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv762. dbms_photoshop , заинтересовала ваша фраза: Код: plsql 1. Можете для моего примера написать, как это можно обойти? Для поднятия общей образованности. Сам придумать не могу. Спасибо. Код: 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.12.2017, 20:51 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
AmKadРавенства по номеру счета должно хватить.С удовольствием посмотрю на твое решение, учитывая что для одного счета может быть дохрена записей 4 и 5 из cum_money_in_out_hist niv76 Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. и их необходимо схлопнуть учитывая условие для self join Код: plsql 1. 2. 3. Можно обойтись без джойна с помощью model, но это баловство. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 21:07 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopучитывая что для одного счета может быть дохрена записей 4 и 5 из cum_money_in_out_histНу вот чтобы не гадать, пусть автор дает данные, обладающие свойствами реальных. И посмотрим, что можно с ними сделать. Правда я оперативность ответа не гарантирую, не знаю когда до оракла доберусь. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 21:38 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
AmKad, Автор получив ответы на свои вполне может потерять интерес к теме. Я до Оракла доберусь в 2018, но могу дать заготовку. Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Думаю, очевидно, что не стоит заклыдваться что здесь по одной строке на 4 и 5. Я не тороплю. :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.12.2017, 22:12 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
dbms_photoshopДумаю, очевидно, что не стоит заклыдваться что здесь по одной строке на 4 и 5. А если предположить, что trade_id суть идентификатор сделки, при этом интересуют только сделки, содержащие ровно по одному участнику на каждой из сторон? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2017, 01:35 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
andrey_anonymous, Да там мутняк отчасти, то что я вижу это сделки в приделах одного счета. Но сделка должна быть между разными клиентами и разными валютами, что, по моему, делаеться только через SWIFT в Украине. Но вот что удивляет, что ищут MAX(settlement_id) могу только предполагать что это идентификатор валютных операций и если нет конвертации он равен 0 например. Посему мне кажеться что это и есть достаточный признак для того чтоб сказать что была конвертация. А то что не через себя (c1.client_id <> c2.client_id), можно проверить и по другому т.к. client_id - primary key. В общем очень бы хотелось увидеть пример от автора, не обязательно много (сотни) клиентов, на 2-х, 3-х все будет понятно. Потому как у меня не очень сходится если на один счет (a.account_id = 1) будет 3 клиента со сделками ct1.dc_type_id = 4 какой информативности будет единый результат MAX(settlement_id) ... это говорит или об утере данных о 2 сделках клиентов, или что с ct1.dc_type_id = 4 может быть только 1 клиент, или еще хз что. Но постановка/пример хотелось бы увидеть, а то как в хрустальный шар. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.12.2017, 13:57 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
Спасибо за ответы. Поспрашивал немного насчет физического смысла запроса. По сути account_number, я так понял, идетнифицирует одного клиента банка. Client_id - это ид счета в разной валюте. две строки ( ct2.dc_type_id = 4 (transfer from) и ct2.dc_type_id = 5 (transfer to) ) фактически это операция конвертации с одной валюты в другую. Settlement_id - это фактически дата банковского дня. Соответственно строк ct2.dc_type_id = 5 , ct2.dc_type_id = 4 может быть много и не всегда между разными валютами, но всегда между разными client_id. Фактически фильтр на неравенство client_id - избыточный. Попробую сегодня сделать немного репрезентавивных тестовых данных.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2018, 11:58 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
Но фильтр на не равенство валют, актуальный: c1.balance_currency <> c2.balance_currency ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2018, 12:02 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
niv76, Можно так попробовать, если я не запутался =) Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. Т.к. без данных можно только прикидывать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2018, 13:45 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
MaximaXXL, надо еще дописать в конце Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. ... а то может случиться ссылка ct1.dc_type_id = 4 на ct1.dc_type_id = 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2018, 14:41 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
cl_trade_id ПК транзакции. rc_cl_trade_id - ссылка на связанную парную транзакцию. Транзакции dc_type_id in (4,5) могут быль либо одиночными (если деньги заводяться или выводятся из системы). Для таких строк rc_cl_trade_id = NULL. Либо парными - когда деньги перебрасываются в системе между разными счетами (rc_cl_trade_id IS NOT NULL). Скрипт с данными в файле. Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2018, 15:12 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2018, 15:26 |
|
||
|
как хинтами добиться нужного плана
|
|||
|---|---|---|---|
|
#18+
Остался спортивный интерес сделать с группировкой и проверкой c1.balance_currency <> c2.balance_currency, не делая второго джойна ( client c2, cum_money_in_out_hist ct2 ) Похоже даже у самого получилось, может кто-то красивее может: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.01.2018, 15:36 |
|
||
|
|

start [/forum/topic.php?all=1&fid=52&tid=1884639]: |
0ms |
get settings: |
9ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
49ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
85ms |
get tp. blocked users: |
1ms |
| others: | 214ms |
| total: | 390ms |

| 0 / 0 |
