|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
Программа изначально работала с курсором в основном потоке и запускала сохраненную процедуру (proc1 с параметрами) оракла производился анализ результата ее выполнения - в случае успешного завершения - commit; - в случае неудачи - roolback и запуск процедур (proc2 и proc3 с параметрами ) выполняющие корректное завершение операции в БД и логирование В связи с тем, что список записей, формируемых курсором постоянно увеличивается, а скорость выполнения процедуры proc1 остается достаточно низкой ( от 1 до 30 секунд), общее время отработки списка становится неприемлемым. Оптимизировать скорость выполнения процедур путем внедрения исправлений в код - шаг нетривиальный и скорее всего неприемлемый поскольку сразу теряется тех поддержка разработчиков установленного БД Для решения данного вопросы было принято решение сделать многопоточный запуск процедуры proc1 и proc2 proc3 соответственно. Для того что бы не перегрузить сервер количество потоков должно быть не более N (в нашем случае 20). При анализе вопросов на форуме натолкнулся на "вопрос по SharedObject" ( http://www.sql.ru/forum/actualthread.aspx?tid=104627&hl=thread ) представленный потоковый обьект и обьект коммуникации от Филлипа, как мне кажется могут подойти для решения этой задачи. Вопрос в том - как эти кубики сложить в единую схему? Где производить подсчет threads? Как их запускать? Можно ли использовать эти 2 обьекта в глобальной процедуре ( сейчас так и работает - в одном потоке) или необходимо создать nonvisual userobject (обязательно ли это) ? Не смогли бы уважаемые профессионалы помочь разобраться с этими наболевшими вопросами. Заранее Вам благодарен. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2006, 12:26 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
(Дополнение) Чтобы не быть голословным приведу укороченный код процедуры Dec Oper_id datetime Oper_date string Oper_RetCode, Oper_RetMessage, Oper_ErrMessage, Oper_ErrCode, tmp_data, Log_Name Integer tmp_id,Person_ID, i, j, Ok_Command, Bad_Command Boolean Is_Error work_log('Подтверждение в базе данных...') // процедура proc1 DECLARE Set_WO_ADP PROCEDURE FOR WorkOrders_API.Set_WO_Adopted(:Oper_id, :Oper_date, :Person_ID) USING sqlca; // процедура proc2 DECLARE Set_WO_ERR PROCEDURE FOR WorkOrders_API.Set_WO_Error(:Oper_id) USING sqlca; // процедура proc3 DECLARE Set_WO_INS PROCEDURE FOR WorkOrders_API.Insert_WO_Error (:Oper_id, 1, :Oper_ErrCode, :Oper_ErrMessage) USING sqlca; // Собственно подтверждение startprogress(UpperBound(List_Order)) for i=1 to UpperBound(List_Order) progress() If List_Order .Flag = confirm then Oper_id = List_Order[Sort_Order].Current_ID select sysdate into :Oper_date from dual; Oper_RetCode = '' Oper_RetMessage = '' Oper_ErrMessage = '' Oper_ErrCode = '' execute set_WO_ADP; fetch set_WO_ADP into :Oper_RetCode, :Oper_RetMessage; if Oper_RetCode = '0' then // Усе Ок commit; else // были ошибки ПОДТВЕРЖДЕНИЯ Oper_ErrMessage = Oper_RetMessage Oper_ErrCode = Oper_RetCode Rollback; Execute Set_WO_ERR; fetch set_WO_ERR into :Oper_ErrCode, :Oper_ErrMessage; Execute Set_WO_INS; fetch set_WO_INS into :Oper_ErrCode, :Oper_ErrMessage; Commit; Error_Log('Подтверждение в базе данных', 0) end if end if next stopprogress() return ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2006, 13:22 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
OutcastПрограмма изначально работала с курсором в основном потоке и запускала сохраненную процедуру (proc1 с параметрами) оракла производился анализ результата ее выполнения - в случае успешного завершения - commit; - в случае неудачи - roolback и запуск процедур (proc2 и proc3 с параметрами ) выполняющие корректное завершение операции в БД и логирование Каким образом выше выделенное может быть решено многопоточным запуском процедуры proc1 и proc2 proc3 соответственно? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2006, 18:38 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
ФилиппКаким образом выше выделенное может быть решено многопоточным запуском процедуры proc1 и proc2 proc3 соответственно? Вместо запуска этого алгоритма 20 раз последовательно, хотят запускать его 20 раз но паралельно. т.е. снизить общее время выполнения в разы. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2006, 19:16 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
Dmitry. ФилиппКаким образом выше выделенное может быть решено многопоточным запуском процедуры proc1 и proc2 proc3 соответственно? Вместо запуска этого алгоритма 20 раз последовательно, хотят запускать его 20 раз но паралельно. т.е. снизить общее время выполнения в разы. Хорошо если так. Я лично это прочитал так, что хотят proc1 в отдельный поток, proc2 в отдельный и proc3 в отдельный... Каков вопрос, таков и вопрос :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2006, 19:38 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
да это можно реализовать. надо создать : невизуальный обьект для слушания Код: plaintext
невидимый обьект с ф-цией со всеми нужными параметрами Код: plaintext
Код: plaintext
-- далее код типа: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
причем все это может быть в локаторе. и локатор-же может менеджить (считать, запускать, слушать) потоки ... |
|||
:
Нравится:
Не нравится:
|
|||
26.06.2006, 20:14 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
Dmitry. ФилиппКаким образом выше выделенное может быть решено многопоточным запуском процедуры proc1 и proc2 proc3 соответственно? Вместо запуска этого алгоритма 20 раз последовательно, хотят запускать его 20 раз но паралельно. т.е. снизить общее время выполнения в разы. Правда с таким же успехом можно получить и замедление в несколько раз :-( Лучше для начала провести эсперимент... OutcastОптимизировать... процедур путем внедрения исправлений в код - шаг нетривиальный и скорее всего неприемлемый поскольку сразу теряется тех поддержка разработчиков установленного БД Весьма странный подход, когда для ускорения работы серверной компоненты, правится клиентская часть. Чем и хорош SQL сервер, что в нем не обязательно исправлять исходные процедуры, можно написать свои паралельные, оптимизированные. Дописывание надеюсь не приводит к "потере поддержки"? Как вариант таки заставить разработчиков оптимизировать это хозяйство, если нет править самому, нахрен такая поддержка нужна. Ну и последнее я не специалист по ORACLE, но судя по опыту в SQL, практически все что делается курсором можно сделать проще, быстрее и надежнее, без курсора. Обрабатывая записи пакетом и соответственно избавившись от линейной зависимости времени от количества записей. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 15:09 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
Вообще-то, Estets все слова сказал уже :-) Но тут вот у меня пара замечаний относительно кода клиентского 1. Не самый лучший способ определения границы цикла, Outcast Код: plaintext
2.при отработке пакета в цикле действительно принципиально передавать в процедуру точное время вызова для каждого элемента массива? Outcast Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 16:16 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
To PL99 При отработке каждого запроса действительно необходимо точное время подтверждения запроса. И время именно с сервера. UpperBounds же использовал для определения размера динамического массива ListOrder, который в свою очередь собирался из курсора. При каждом запуске количество записей в массиве различно (от 1 до 5000 прибл.). To Dmitry Да, Вы правы, мы действительно хотим в разы повысить производительность подтверждений запросов путем распараллеливания запуска процедуры proc1 Правда Ваш код в этом случае будет отрабатывать N (=20) запросов за время, равное самому длительному подтверждению из N. Это возможно волне приемлемое решение. Спасибо. Для ускорения предложенного решение есть идея подтверждения производить поточно и по мере отработки каждого потока подзагружать свежими данными. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 16:34 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
OutcastПравда Ваш код в этом случае будет отрабатывать N (=20) запросов за время, равное самому длительному подтверждению из N. Это возможно волне приемлемое решение. Спасибо. Именно тут на мой взгляд и кроется ошибка, код будет отрабатывать, точно дольше чем "время, равное самому длительному подтверждению из N", возможно за время "сумма всех времен выполнения 1..N", может меньше, может больше, это уже зависит от количества процессоров на сервере, настроек самого сервера и много чего еще. И не стоит забывать о такой проблеме ORACLE как возможный Rollback в одном из потоков, на сколько вырастет сегмент отката (если не ошибаюсь) при выполнении не одной а 20 процедур. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 16:53 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
To Estets Не знаю, что сказать Вам на этот счет ))) (Подробности же Вас не интересуют, не правда ли? ) Меня же интересует "принципиальная схема механизма параллельного запуска хранимых процедур" на клиенте. Линейного возрастания скорости я не жду - это и ежу понятно, но качественного ускорения добиться этим можно. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 16:58 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
OutcastTo PL99 При отработке каждого запроса действительно необходимо точное время подтверждения запроса. И время именно с сервера. UpperBounds же использовал для определения размера динамического массива ListOrder, который в свою очередь собирался из курсора. При каждом запуске количество записей в массиве различно (от 1 до 5000 прибл.). Гм... Я имел ввиду то, что количество записей в массиве следует определять не во время , а до цикла. Тоже самое относилось и к дате, передаваемой в процедуру. Ну, и уж до кучи, а почему Вы не проверяете успешность вызова процедур? Код: plaintext 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 17:03 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
To PL99 процедура определения верхней границы отрабатывает единожды как раз до цикла, далее значение сохраняется уже в коде цикла. Конечно можно это было сделать и через переменную. А вот время - длительность подтверждения варьируется (от секунды и более) В этом случае значение времени будет не совпадать с истинным. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 17:13 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
Outcastпроцедура определения верхней границы отрабатывает единожды как раз до цикла, далее значение сохраняется уже в коде цикла. Конечно можно это было сделать и через переменную.Граница цикла For в случае вызова через UpperBound определяется для каждой итерации, поэтому сделать через переменную было бы аккуратнее. OutcastА вот время - длительность подтверждения варьируется (от секунды и более) В этом случае значение времени будет не совпадать с истинным.Понятно, это сомнений не вызывает. Но вот физический смысл подобного действия... У вас процесс подтверждения документов инициирован пользователем (я такой вывод сделал на основании того, что вы выводите progresbar). Не логичнее ли считать, что все документы, подтвержденные в результате этого процесса, обработаны в одно и тоже время? Впрочем, не смею настаивать на этой точке зрения, т.к. бизнес-процесс мы здесь не обсуждаем. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 17:34 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
OutcastНе знаю, что сказать Вам на этот счет ))) (Подробности же Вас не интересуют, не правда ли? ) Если бы не интересовало, то я бы не встревал в разговор. Outcast Меня же интересует "принципиальная схема механизма параллельного запуска хранимых процедур" на клиенте. Линейного возрастания скорости я не жду - это и ежу понятно, но качественного ускорения добиться этим можно. У меня была практически аналогичная задача, по проведению документов и решалась примерно так же, DW со списком идентификаторов, и бегущий курсорчик вызывающий ХП с нужным идентификатором и отмечающий в списке галочку/крестик по итогам выполнения процедуры. 100 документов - 200 секунд. Была поставлена задача повести 10 000 документов за 2 000 секунд АКА пол часа. Вообщем задача была решена, но решена именно: 1) Оптимизацией самой ХП, оптимизацией логики, выкидыванием ненужных проверок, укорением нужных проверок и т.п. 2) Переносом всей обработки на сервер, т.е. на сервере в ХП формируется временная таблица с нужными данными и исползуется уже серверный курсор для вызова ХП-проведения. Этим мы убираем потери на сеть и вызов ХП с клиента. Все это дало ускорение в 15 раз, правда никаких красивостей на клиенте не отображалось типа галочек и прогресс-баров. Это один из вариантов решения ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 17:42 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
P.S. Запусть паралельно еще один поток мне даже не пришло в голову, потому что есть у меня подозрение что если это и даст ускорение, то 20-30% а это меня не устраивало. P.P.S Если бы мне надо было ускорить выполнение на 2 порядка, то я бы смотрел именно на пакетную обработку, хотя в процедуре проведения сложная логика создания проводок, около 15 insert-ов и select-ов вообще более 30, но только пакетная обработка возможно позволила бы решить такую задачу. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 18:00 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
To Estets Вы затронули интересную сторону оптимизации. Не могли бы Вы поподробнее с нею ознакомить (пакетная обработка). Просто в своей программе мы используем АПИ разработчика БД (около 800 таблиц - биллинг) Возможно ли в пакетной обработке использовать эти же процедуры АПИ? Самим же писать низкоуровневую логику обработки запросов... ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 18:17 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
TO PL99 Своими замечаниями (на счет времени) Вы мне подсказали альтернативный метод подсчета - вначале в переменную сохраняется время сервера, а после этого только к нему добавляется дельта предыдущего времени отработки - таким образом точность - в допустимых пределах и лишних обращений нет. Спасибо. ... |
|||
:
Нравится:
Не нравится:
|
|||
27.06.2006, 18:32 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
OutcastTo Estets Вы затронули интересную сторону оптимизации. Не могли бы Вы поподробнее с нею ознакомить (пакетная обработка). Просто в своей программе мы используем АПИ разработчика БД (около 800 таблиц - биллинг) Возможно ли в пакетной обработке использовать эти же процедуры АПИ? Самим же писать низкоуровневую логику обработки запросов... Если использовать АПИ разработчика, то на мой взгляд проще всего перенести курсор в сервер, на этом можно достаточно сильно оптимизировать время выполнения. Все остальное уже требует влезание в код разработчика, или написание паралельного кода.Например у нас в процедуре проведения документа проверялся пользователь и его права на выполнение данной операции, хоть это занимало и мало времени, но если умножить время на 10 000 операций то получалось огого. Соответственно проверку прав пользователя вынесли в процедуру с курсором, которая выполняется один раз и вызывает в цикле процедуры проведения уже без проверки. А вот массовая обработка требует именно "Самим же писать низкоуровневую логику", на свой страх и риск. Например есть процедура которая записывает запись в лог и вызывается для каждого документа. Если она отрабатывает 0.1 сек то 10 000 * 0.1 = 1.5 мин. А если заменить ее на Код: plaintext 1. 2.
Если требуется расчеты то ожно почитать советы ASCRUS в "Проектировании БД" о предварительных расчетах агрегатных сумм именно для разрыва линейной зависимости времени расчетов от количества документов. Но все это достаточно спецефично, и дать общий совет не зная вашей задачи вряд ли у кого получится. ... |
|||
:
Нравится:
Не нравится:
|
|||
28.06.2006, 11:42 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
а мне интересно что получится с потоками. ..хотя и решение с массовой обработкой значительно лучше ... |
|||
:
Нравится:
Не нравится:
|
|||
29.06.2006, 10:56 |
|
Работа с сохраненными процедурами в thread (PB 6.5, Oracle 8i)
|
|||
---|---|---|---|
#18+
вот пару классов по theads ... |
|||
:
Нравится:
Не нравится:
|
|||
29.06.2006, 19:45 |
|
|
start [/forum/topic.php?fid=15&msg=33817553&tid=1337703]: |
0ms |
get settings: |
11ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
33ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
62ms |
get tp. blocked users: |
2ms |
others: | 267ms |
total: | 412ms |
0 / 0 |