10.09.2008, 16:39 | #1 |
Участник
|
Падение производительности при разноске производственного журнала
Dynamics Ax 4.0 kernel 4.0.2501.116 Application version 4.0.2200.0
Уважаемые коллеги. Ситуация следующая. У клиента установлен модуль "Производство" и персонал осуществляет сборку спецификаций через журналы приемки и отборочные накладные. Пример: создан производственный заказ на 10000 единиц номенклатуры. В сборочном цехе для каждой единицы продукции создается отдельный журнал приемки с количеством = 1, для которого средствами Аксапты генерится отборочная накладная, содержащая спецификацию. В эту отборочную накладную вносится информация о серийных номерах данной сборки, после чего накладная разносится, а потом разносится и журнал приемки. Цикл повторяется пока все 10000 изделий не будут собраны. Проблема в следующем: пока количество привязанных к данному производственному заказу журналов не превышает нескольких десятков, разноска каждого следующего журнала занимает не очень много времени. Но с ростом числа таких журналов время, занимаемое разноской журнала, растет по экспоненте и после разноски нескольких сотен журналов приемки для данного производственного заказа превышает все допустимые пределы для производственного процесса. В чем может быть причина такого замедления процесса разноски? Заранее благодарен за любые идеи и хинты. |
|
10.09.2008, 16:52 | #2 |
Moderator
|
Перенес из Программирования в Администрирование. Коллеги, давайте внимательнее выбирать раздел для темы.
__________________
Андрей. |
|
10.09.2008, 16:56 | #3 |
Участник
|
На самом деле я считаю что вопрос скорее к разработчикам нежели к администраторам. Вряд ли администраторы представляют себе, как работает алгоритм разноски журналов, и в каком месте число прикрепленных к производственному заказу журналов может влиять на скорость разноски. Поправьте меня если я ошибаюсь.
|
|
10.09.2008, 17:14 | #4 |
Moderator
|
По мне - данная тема, если разобраться, вообще претендент сразу для 3х разделов: Администрирование, Функционал, Программирование. Посмотрим, что посоветуют специалисты для решения проблемы, и тогда уже тему при необходимости перенесу.
__________________
Андрей. |
|
|
За это сообщение автора поблагодарили: evv (1). |
10.09.2008, 17:40 | #5 |
Участник
|
Если есть время поэкспериментировать, то отключите (на копии базы и приложения) корреспонденцию счетов (параметры Главной книги) и попробуйте разнести без нее, если конечно в вашем случае они вообще создаются.
Тут проскакивали темы про долгую разноску складских журналов (правда в основном в тройке), может еще эта грабля осталась. |
|
10.09.2008, 17:44 | #6 |
Участник
|
Спасибо за участие в дискуссии. Нет, клиент западный и корреспонденцией счетов в принципе не занимается. Локализация западно-европейская, то есть без российской функциональности вообще.
|
|
10.09.2008, 17:46 | #7 |
Участник
|
|
|
10.09.2008, 18:03 | #8 |
Участник
|
вот например Разноска складского журнала в 10000 строк.
а конкретно про проблеме долгой разноски из-за ГК писал fed в статье про ГК. Ссыкла тут Немного об архитектуре разноски в ГК и проблеме корреспонденции счетов, там где-то в начале, по-моему. Но это только про тормоза из-за корреспонденции счетов |
|
10.09.2008, 18:46 | #9 |
----------------
|
Обычно так себя проявляет использование какого-то большого временного хранилища (временная таблица и т.п.) общего для всего процесса, по которому делается поиск ранее проведенных операций.
Характерной особенностью является активная работа диском на клиенте или АОСе. Можно запустить FileMon какой-нибудь и увидеть какой файл Аксапта много читает и чуть-чуть пишит... но как понять где это в коде не придумал еще. |
|
|
За это сообщение автора поблагодарили: evv (1). |
11.09.2008, 09:30 | #10 |
Участник
|
Уважаемые коллеги! Большое спасибо всем, кто принял участие в обсуждении. Проблему удалось решить несколько другим путем. Как выяснилось, при разноске производственного журнала Аксапта пересчитывает мгновенную себестоимость изделия, и этот расчет ведется по всем записям в InventTrans, связанных с конкретным производственным заказом. Просто закомментировав вызов данного расчета, мы добились того, что разноска производственного журнала занимает одно и то же время (несколько секунд) вне зависимости от того, сколько производственных журналов для данного заказа уже разнесено. Вызов находится в методе postTransLedger класса ProdJournalCheckPostBom,
в самом конце метода есть такие строчки: X++: // Update ProdCalcTrans if(!ProdTableJour::isHistoricalCost(prodTable.ProdId)) ProdCalcTrans::updateRealCalcBOM(prodTable, prodBOM); |
|
11.09.2008, 09:33 | #11 |
Участник
|
Все-таки предлагаю перенести эту тему назад в раздел Разработка, если не возражаете
|
|
11.09.2008, 10:02 | #12 |
Moderator
|
Я-то перенесу, но вот такое "простое" решение что-то у меня вызывает сомнения...
В производственном модуле не специалист, поэтому правильность прокомментировать не могу. Хотя охотно Вам верю, что ускорения вы добились
__________________
Андрей. |
|
11.09.2008, 11:17 | #13 |
Участник
|
Жизнь покажет, где мы ошибались Просто насколько мне известно, себестоимость считается для всего заказа приего закрытии в любом случае, так что вроде мгновенные расчеты не нужны. Зато клиент может работать и радоваться. Во всяком случае пока Кроме того, вопрос о необходимости таких расчетов уже обсуждается с ключевыми пользователями клиента, так что проблема, если она есть, будет известна не слишком поздно.
|
|
11.09.2008, 12:33 | #14 |
Участник
|
Цитата:
Думаю, что надо дальше искать и анализировать тяжелые запросы. Внутри есть ProdCalcTrans::updateRealCalcCostBreakdown(prodCalcTrans, _prodBOM, inventItemPrice); там достаточно тяжелые запросы, которые зависят от количества строк... думаю, что надо рыть дальше в чисто административном плане. Отключать функционал не есть гуд. Тем более комментированием. |
|
11.09.2008, 12:47 | #15 |
Модератор
|
Уверен?
\Data Dictionary\Tables\ProdBOM\Methods\calcCostAmount X++: container calcRealCostAmount() { InventTrans inventTrans; InventDimParm inventDimParmFinancial; InventDimParm inventDimParmActive; InventDimGroupId dimGroupId; InventQty qty = 0; CostAmount value = 0; boolean first = true; ; while select inventTrans // !!! index hint TransIdIdx where inventTrans.InventTransId == this.InventTransId && inventTrans.ItemId == this.ItemId && inventTrans.StatusIssue == StatusIssue::Deducted && inventTrans.ValueOpen == InventTransOpen::Yes && inventTrans.PackingSlipReturned == NoYes::No { if (first) { dimGroupId = InventTable::find(inventTrans.ItemId).DimGroupId; inventDimParmFinancial.initFinancialInvent(dimGroupId); inventDimParmActive.initDimActive(dimGroupId); first = false; } qty += inventTrans.Qty; value += inventTrans.estimatedCostValue(inventDimParmFinancial,inventDimParmActive); /// !!! } qty = abs(qty); value = abs(value); return [qty,value]; }
__________________
-ТСЯ или -ТЬСЯ ? |
|
11.09.2008, 12:59 | #16 |
Участник
|
Уверен, что не комментировать вызов целого метода, а работать с конкретными запросами. Например, с тем, что ты привел.
самое тяжелое в указанном тобой методе - получить сумму ожидаемых себестоимостей. для каждого вызова в свою очередь вызывается X++: [qty,value] = InventTrans::calcMarkedCostValue(this.InventRefTransId,this.ItemId,this.InventDimId,this.inventTable().inventModelGroup().InclPhysicalValueInCost,this.InventTransId); В результате имеем кучу вложенных достаточно тяжелых запросов. Вот с этим и надо разбираться, а не "Просто закомментировав вызов данного расчета" |
|
|
За это сообщение автора поблагодарили: evv (1). |
12.09.2008, 11:35 | #17 |
Участник
|
Цитата:
Сообщение от mazzy
Уверен, что не комментировать вызов целого метода, а работать с конкретными запросами. Например, с тем, что ты привел.
самое тяжелое в указанном тобой методе - получить сумму ожидаемых себестоимостей. для каждого вызова в свою очередь вызывается X++: [qty,value] = InventTrans::calcMarkedCostValue(this.InventRefTransId,this.ItemId,this.InventDimId,this.inventTable().inventModelGroup().InclPhysicalValueInCost,this.InventTransId); В результате имеем кучу вложенных достаточно тяжелых запросов. Вот с этим и надо разбираться, а не "Просто закомментировав вызов данного расчета" |
|
12.09.2008, 22:00 | #18 |
Участник
|
Мне кажется проблема все таки в том что вызов происходит на каждую разноску журнала, разноска идет на каждую единицу номенлкатуры. В итоге получаем квадратичную зависимость от числа единиц принимаемой номенклатуры.
Оптимизация запросов скорее всего не поможет. Я бы лучше все таки код внимательно проанализировал. Есть ощущение что можно оставить это место закомментированным, но перенести вызов позже, после разноски всех журналов. Тогда ничего не должно отвалиться, но уйдут ненужные вызовы. |
|