Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
База DB2 Есть запрос который должен считать количество карточек НЗ и средне время исполнения НЗ. Запрос выполняется порядка 8 минут если у брать убрать условие WS_con.status ='CONTR' запрос исполняется за 3,5 секунды. Что странно аналогичное условие по этой же таблице уже есть WS.status ='COMP' и его наличие на производительность никак не влияет. Помоги разобраться. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 12:21 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
PSD, в вопросах производительности запросов всегда нужно начинать с просмотра их планов выполнения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 12:58 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
PSD, На 8.2 и на 9.1 сталкивался с какой-то "фигней" при использовании сравнения varchar полей, допускающих NULL. В общем, запрос со сравнением вида Код: sql 1. работал быстрее, чем запрос с условием вида Код: sql 1. . P.S. вместо ucase м.б. другая подходящая по смыслу строковая функция. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 14:52 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
Вещей вроде ""Cost Based Oracle Fundamentals" by Jonathan Lewis" "у нас" нет, это довольно обидно, но почитайте хотя бы её. Ленивый вариант - натравите на свой запрос db2advis, он может что-нибудь полезное насоветовать. Я обычно так оптимизирую ;-). Я предполагаю также, что статистика runstats with distribution and detailed indexes all у вас собрана. Может, при этом количество частот и квантилей имеет смысл поднять. Возможный механизм проблемы: добавление дополнительного условия резко снижает оценку, начинает использоваться loop join по индексу вместо предыдущего hash join фуллсканом то таблице или индексу, тогда как оценка резко не совпадает с действительностью и нужен именно hash join. Надо сравнивать планы, оценки, реальные количества в узлах, прикинуть, не нужна ли многоколоночная статистика. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 15:17 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
PSD, Условием WS_con.status ='CONTR' вы заставляете db2 обращаться к: left join maximo.WOSTATUS WS_con on WS_con.WONUM=PM.WONUM а условием WS.status ='COMP' - к: from maximo.WOSTATUS WS Таблица-то та же, только в первом случае вы заставляете 2-й раз к ней обращаться. Без условия на WS_con.status оно может даже 2-й раз вообще не обращаться к этой таблице (как будто этого left join вообще нет). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 15:33 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
авторУсловием WS_con.status ='CONTR' вы заставляете db2 обращаться к: left join maximo.WOSTATUS WS_con on WS_con.WONUM=PM.WONUM а условием WS.status ='COMP' - к: from maximo.WOSTATUS WS Таблица-то та же, только в первом случае вы заставляете 2-й раз к ней обращаться. Без условия на WS_con.status оно может даже 2-й раз вообще не обращаться к этой таблице (как будто этого left join вообще нет). Вы имеете ввиду что WS.status ='COMP' порождает пробег по произведению таблиц PM и WOSTATUS ? Что вы посоветуете сделать в данном случае? Пробовал заменить left join maximo.WOSTATUS WS_con on WS_con.WONUM=PM.WONUM на left join (select * from maximo.WOSTATUS where maximo.WOSTATUS.status ='CONTR') WS_con on WS_con.WONUM=PM.WONUM Результат тот же. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 17:34 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
PSD, непонятно вообще, для чего ты используешь там половину LEFT JOIN-ов, если всё одно в WHERE срезаешь результат внешнего соединения до банального INNER JOIN... вот смотри на WHERE: 1) and pm.PMNUM is not null and pm.MONTHPLAN is not null срезают left join maximo.WORKORDER PM on WS.WONUM=PM.WONUM до INNER-а 2) and L_MR.SHORTPATH like 'ПСПП/МУ/МГВП/%' срезает left join maximo.LOCATIONS L_MR on cs.PODRM=L_MR.LOCATION до INNER-а 3) and WS_con.status ='CONTR' срезает left join maximo.WOSTATUS WS_con on WS_con.WONUM=PM.WONUM до INNER-а Так зачем усложнять жизнь серверу и требовать от него OUTER-соединения? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 18:18 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
PSD, Дело не в этом. Вы можете объяснить, почему вы делаете так: from maximo.WOSTATUS WS left join maximo.WORKORDER PM on WS.WONUM=PM.WONUM left join maximo.COMMODITIES CG on PM.COMMODITYGROUP = CG.COMMODITY left join maximo.COMMODITIES CS on PM.COMMODITY = CS.COMMODITY left join maximo.LOCATIONS L_PG on PM.PRED = L_PG.LOCATION left join maximo.LOCATIONS L_MR on cs.PODRM=L_MR.LOCATION left join maximo.WOSTATUS WS_con on WS_con.WONUM=PM.WONUM where WS.status ='COMP' and WS.CHANGEDATE between '2015-09-01' and '2015-11-01' and WS_con.status ='CONTR' ... а не так: from maximo.WOSTATUS WS left join maximo.WORKORDER PM on WS.WONUM=PM.WONUM left join maximo.COMMODITIES CG on PM.COMMODITYGROUP = CG.COMMODITY left join maximo.COMMODITIES CS on PM.COMMODITY = CS.COMMODITY left join maximo.LOCATIONS L_PG on PM.PRED = L_PG.LOCATION left join maximo.LOCATIONS L_MR on cs.PODRM=L_MR.LOCATION where WS.status ='COMP' and WS.CHANGEDATE between '2015-09-01' and '2015-11-01' and WS.status ='CONTR' ... Т.е. зачем вы вообще второй раз к этой таблице обращаетесь по другому корр. имени? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 18:21 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
Тут, наверное, надо логику хранения и извлечения данных понимать. Т.е. что именно вы хотите этим запросом возвратить, какой смысл этого поля maximo.WOSTATUS.WONUM (оно уникальное или нет, или пара WONUM, STATUS уникальная, если нет - покажите хоть пример того, что там в этих таблицах вообще хранится, как они связаны между собой). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2015, 18:30 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
Mark Barinstein, Код: sql 1. 2. Такой вариант не пойдет , WS.status не может быть одновременно и 'COMP' и 'CONTR' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2015, 13:00 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
PSDТакой вариант не пойдет , WS.status не может быть одновременно и 'COMP' и 'CONTR'Это да, я ошибся. Вы должны понять, что с этим дополнительным условием это просто 2 разных запроса. Сравните результат этого запроса, и запроса с раскомментированными строками. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Во втором случае оптимизатору по каждой найденной записи в WOSTATUS с условием WS.status ='COMP' and WS.CHANGEDATE between '2015-09-01' and '2015-11-01' надо будет еще раз залезть в ту же таблицу, чтобы узнать, а есть ли по этому же WONUM еще записи с другим STATUS. Гораздо больше работы надо сделать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2015, 13:56 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
У меня нет желания вникать в таким образом написанный и отформатированный запрос на непонятных данных, но выскажусь всё равно ;-). Как может добавление условия затормозить запрос? Вот один из сценариев: Положим, у нас есть таблица T1 с C1 (cardinality) записей. Предикат P11 оставляет в выборке S11*C1 записей, то есть SELECT count(*) FROM T1 WHERE P11 возвращает S11*C1. (S11 - это дробное число между 0 и 1, selectivity) Аналогично, Предикат P12 оставляет S12*C1 записей SELECT count(*) FROM T1 WHERE P12 возвращает S12*C1. Сколько будет SELECT count(*) FROM T1 WHERE P11 AND P12? Да сколько угодно в некоторых пределах - от нуля до минимума между S11*C1 и S12*C1, то есть цифра могла вообще не поменяться. Но если, положим, оптимизатор правильно оценивает селективность как S11 и S12, то без мультиколоночной статистики он возьмёт число S11*S12. Теперь, чем это грозит. был SELECT ... FROM T1 JOIN T2 ON ... WHERE P1 стал SELECT ... FROM T1 JOIN T2 ON ... WHERE P1 AND P2 и положим, что при выполнении соединения "внешняя" таблица T1, а "внутренняя" T2. Самыми распространёнными путями доступа к данным джойна являются NLJOIN и HASH JOIN. NLJOIN "обычно" идёт по индексу, и хорошо это тогда, когда записей от T1 в цикле участвует очень-очень "мало" - в противном случае море одноблочных обращений приводит к тормозам. Доступ по хешу гораздо более годится, когда от T1 участвует "много" записей. И если добавление предиката P2 привело к заниженной оценке, и оттого правильный в данной ситуации HASH JOIN сменился на NLJOIN, потому что оптимизатор посчитал, что строк будет много меньше, чем оказалось на самом деле, начались тормоза. К запросу топикстартера это может иметь отношение, а может не иметь, но планы-таки надо анализировать. Одна из вещей, которыми меня огорчает DB2 в данном аспекте, это что actuals идут за дополнительную плату (Workload Management), то есть в Express-C их не увидеть. И counts надо будет считать вручную, примерно как мы видим в старых статьях на developerworks. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2015, 15:03 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
Victor MetelitsaОдна из вещей, которыми меня огорчает DB2 в данном аспекте, это что actuals идут за дополнительную плату (Workload Management), то есть в Express-C их не увидеть. И counts надо будет считать вручную, примерно как мы видим в старых статьях на developerworks. Виктор, Возможность получения section actuals никах не связана с WLM. Я не пробовал именно с Express-C, но оно там должно быть доступно. Вам разрешено пользоваться WLM функциями, например, такими как WLM_SET_CONN_ENV. Пока вы не создаете объектов WLM (event monitor for activities к ним не относится). У вас что, не работает на Express-C что-то из этого: - CREATE EVENT MONITOR ACT FOR ACTIVITIES ... - Включение сбора для своего (или для другого, если handle известен) соединения CALL WLM_SET_CONN_ENV(NULL, '<collectactdata>WITH DETAILS, SECTION</collectactdata><collectsectionactuals>BASE</collectsectionactuals>' ); - query ... - Выключение CALL WLM_SET_CONN_ENV(NULL, '<collectactdata>NONE</collectactdata><collectsectionactuals>NONE</collectsectionactuals>' ); - Поиск запроса в таблицах, нахождение параметров для процедуры, заполнение explain таблиц CALL EXPLAIN_FROM_ACTIVITY ... - форматирование db2exfmt ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2015, 16:03 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
Спасибо. Я был настолько уверен, что не удосужился проверить (причём не раз обжигался). То есть, я что-то такое уже проверял, оно не работало, жалуясь на лицензионные ограничения, и я бросил это дело. А вот это, похоже, работает. Ну, тем лучше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2015, 18:12 |
|
||
|
Почему добавление еще одного условия в запрос увеличивает время исполнения в сотни раз
|
|||
|---|---|---|---|
|
#18+
Mark BarinsteinPSDТакой вариант не пойдет , WS.status не может быть одновременно и 'COMP' и 'CONTR'Это да, я ошибся. Но мысль была правильная, я добавлял второй join потому что для дальнейших вычислений мне гораздо удобней иметь все необходимые данные в одной записи, но так как запись которая выбирается по условию WS.status ='COMP' and WS.CHANGEDATE between '2015-09-01' and '2015-11-01' в дальнейших вычислениях не участвует (она нужна только для того чтобы найти в WORKORDER нужные записи) то действительно можно получать все данные через один join а затем перед агрегацией отфильтровать. в итоге получился следующий запрос с временем исполнения 2,3 секунды. Код: sql 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. Всем спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2015, 15:07 |
|
||
|
|

start [/forum/topic.php?fid=43&msg=39107028&tid=1600700]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
63ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 297ms |
| total: | 449ms |

| 0 / 0 |
