AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: База знаний и проекты
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 31.03.2007, 15:17   #1  
SHiSHok is offline
SHiSHok
Участник
Аватар для SHiSHok
Дети Юза
 
219 / 103 (4) +++++
Регистрация: 28.07.2005
Адрес: Донецк
Lightbulb тупость при удалении из InventJournalTrans
удаляли сегодня инвентаризационный журнал,я громко матюкался когда обнаружил этот тупняк (88000 строк журнала удалялось 4 часа).
итак таблица: InventJournalTrans
X++:
void delete()
{
    ;
    ttsbegin;
    appl.inventUpdateTTSControl().setTTSBeginLock();

    super();

    if (this.journalType == InventJournalType::Count)
        InventItemLocation::updateStopCountingJournal(this);

    InventUpd_DeleteMovement::newMovement(InventMovement::construct(this)).updateNow();

    if (this.voucher)
    {
        if (this.numOfVoucherLines() == 0) // нас интересует эта строка !!!
            JournalError::deleteVoucher(tableNum(InventJournalTable),this.journalId,this.voucher);
    }

    appl.inventUpdateTTSControl().setTTSCommitLock();
    ttscommit;

}
смотрим метод numOfVoucherLines()
X++:
Integer numOfVoucherLines()
{
    return (select forceplaceholders count(recId) from inventJournalTrans
                index hint VoucherIdx
                where inventJournalTrans.journalId == this.journalId &&
                      inventJournalTrans.voucher   == this.voucher).recId;
}
т.е. для того чтобы узнать есть такие строки или нет мы считаем их количество! и так для каждой строки журнала - я офигел . сделал так:
X++:
// SHiSHok 20070331
boolean voucherLineExist()
{
    return (select firstfast firstonly forceplaceholders recId from inventJournalTrans
            index hint VoucherIdx
            where inventJournalTrans.journalId == this.journalId &&
                  inventJournalTrans.voucher   == this.voucher).recId != 0;
}

void delete()
{
    ;
    ttsbegin;
    appl.inventUpdateTTSControl().setTTSBeginLock();

    super();

    if (this.journalType == InventJournalType::Count)
        InventItemLocation::updateStopCountingJournal(this);

    InventUpd_DeleteMovement::newMovement(InventMovement::construct(this)).updateNow();

    if (this.voucher)
    {
//        if (this.numOfVoucherLines() == 0)  //
        if (!this.voucherLineExist())
            JournalError::deleteVoucher(tableNum(InventJournalTable),this.journalId,this.voucher);
    }

    appl.inventUpdateTTSControl().setTTSCommitLock();
    ttscommit;

}
при удалении подобного журнала на тестовой выдало оценочное время 35мин (грубо говоря в 6 раз прирост производительности)
__________________
--- SHiSHok
За это сообщение автора поблагодарили: mazzy (5), belugin (6), kashperuk (3), konopello (2), fialka (1), bobski (1).
Старый 10.02.2010, 18:24   #2  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
ну, собственно, в 4-й версии таким широким жестом проверяется наличие строк для удаления (метод Delete()) в следующих таблицах:

InventJournalTrans
ProdJournalBOM
ProdJournalProd
ProdJournalRoute
ProjJournalTrans
TutorialJournalTrans
(sic! чему нас учат!)

более нигде этот волшебный метод numOfVoucherLines не вызывается.
__________________
Felix nihil admirari
Старый 10.02.2010, 18:56   #3  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Хоть и было, это давно, но все же спрошу, а действительно ли прирост был в 6 раз, ну или хотя бы в 2 или 3 раза ?

Действительно, подсчет строк не самый, наверное, лучший вариант для определения, есть ли записи в таблице или нет, но замечу, что во всех таблицах, на которых есть этот волшебный метод, присутствует индекс VoucherIdx, в состав, которого входят оба поля, так что подсчет количества строк должен быть сравним с поиском первой записи по времени, по крайней мере для повторных запросов.

Да, на тестовой выдало время 35 мин, а дальше, что ? Думаю, если подождать эти 35 минут, то Progress Bar будет показывать уже совсем другое время (проверял, будет показывать другие числа, на DAX 4.0 (виртуальная машина от MS) ).

На мой взгляд, проблема того, что строки удаляются долго, в том, что все они удаляются в одной транзакции.

Безусловно, при проверке на существование одной записи прирост производительности операции удаления будет, но не в разы.
__________________
Sergey Nefedov
Старый 10.02.2010, 19:05   #4  
fed is offline
fed
Moderator
Аватар для fed
Ex AND Project
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
2,907 / 5717 (196) ++++++++++
Регистрация: 13.03.2002
Адрес: Hüfingen,DE
Стоит помнить, что для складских журналов можно настроить режим, при котором один ваучер выделяется не на строку, а на все строки с одинаковой датой . Для этого случая - гипотеза о сопоставимости времени выполнения count() и загрузки одной строки не срабатывает...
Да и в режиме Номенклатура+дата, выделение нового ваучера происходит только если в очередной строке номенклатура отличается от номенклатуры в предыдущей строке. Если у тебя, скажем, списывается много одинаковой номенклатуры с разными серийными номерами - гипотеза тоже не срабатывает.
Старый 10.02.2010, 19:06   #5  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
да, мне тоже показался прирост совсем незначительным. на 2500 записях я никакого прироста не ощутил. но методы поправил.

кстати, вопрос методологический: а зачем вообще удалять строки из инв. журнала?
__________________
Felix nihil admirari
Старый 10.02.2010, 20:57   #6  
Zabr is offline
Zabr
Участник
Axapta Retail User
 
1,202 / 345 (14) ++++++
Регистрация: 26.06.2002
Адрес: Москва
Цитата:
Сообщение от SRF Посмотреть сообщение
На мой взгляд, проблема того, что строки удаляются долго, в том, что все они удаляются в одной транзакции.
Как раз наоборот. Много мелких транзакций в цикле выполняются заметно дольше, чем одна общая транзакция на весь цикл. Время тратится на отдельное открытие-закрытие каждой мелкой транзакции.
Старый 10.02.2010, 21:32   #7  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,312 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Цитата:
Сообщение от Zabr Посмотреть сообщение
Как раз наоборот. Много мелких транзакций в цикле выполняются заметно дольше, чем одна общая транзакция на весь цикл.
... но при этом на больших объемах данных и при многопользовательской работе это ставит БД колом на время выполнения транзакции. Хотя формально получается быстрее (аналогично тому, что цикл с прогресс-баром крутится медленнее, чем без него, но при этом психологически кажется что быстрее)
__________________
Возможно сделать все. Вопрос времени
Старый 10.02.2010, 22:52   #8  
AraraT® is offline
AraraT®
Участник
1C
 
158 / 106 (4) +++++
Регистрация: 13.01.2006
Адрес: Республика Татарстан, г. Казань
Цитата:
Сообщение от wojzeh Посмотреть сообщение
да, мне тоже показался прирост совсем незначительным. на 2500 записях я никакого прироста не ощутил. но методы поправил.

кстати, вопрос методологический: а зачем вообще удалять строки из инв. журнала?
А смысл разносить фактическое нувое количество если по системе также 0?
Старый 10.02.2010, 22:54   #9  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
а поразвёртнутей можно? я не компетентен в вопросе настолько, чтоб из вопроса на вопрос составить себе ответ.
__________________
Felix nihil admirari
Старый 11.02.2010, 11:15   #10  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от Zabr Посмотреть сообщение
Как раз наоборот. Много мелких транзакций в цикле выполняются заметно дольше, чем одна общая транзакция на весь цикл. Время тратится на отдельное открытие-закрытие каждой мелкой транзакции.
Так ведь куча логов пишется, и чем дольше транзакция открыта, тем больше их пишется, и тем больше памяти используется для этого (чтобы можно было успешно откатить транзакцию в случае сбоя).
Также могут начать возникать блокировки чтения (правда зависит от версии системы и уровня изоляции при чтении - READ_COMMITTED_SNAPSHOT в SQL 2005 говорят проблему эту решает)
И если транзакция будет длится, скажем, 4 часа, но через 3:59 выключат свет в серверной , то после перезагрузки 4 часа БД будет недоступна, пытаясь откатить все эти изменения. То же будет в случае отката по ошибки в процессе обработки (я думаю, что именно по этой причине там сделали создание журнала с ошибками вместо отката всех строк, как в заказах на покупку/продажу).

Поэтому время на открытия/закрытия мелких транзакций выгоднее с точки зрения скорости. Но целостность данных дороже.
Старый 11.02.2010, 11:24   #11  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от wojzeh Посмотреть сообщение
а поразвёртнутей можно? я не компетентен в вопросе настолько, чтоб из вопроса на вопрос составить себе ответ.
AraraT, видимо, имеет ввиду, что когда создаются строки автоматом по всему номенклатурному справочнику, то по многим строкам разница может получиться нулевая. Особенно строки, которых на складе нет (количество 0).
Такие строки и удаляются
Старый 11.02.2010, 12:17   #12  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Цитата:
Сообщение от SRF Посмотреть сообщение
Хоть и было, это давно, но все же спрошу, а действительно ли прирост был в 6 раз, ну или хотя бы в 2 или 3 раза ?

Действительно, подсчет строк не самый, наверное, лучший вариант для определения, есть ли записи в таблице или нет, но замечу, что во всех таблицах, на которых есть этот волшебный метод, присутствует индекс VoucherIdx, в состав, которого входят оба поля, так что подсчет количества строк должен быть сравним с поиском первой записи по времени, по крайней мере для повторных запросов.
Цитата:
Сообщение от fed Посмотреть сообщение
Стоит помнить, что для складских журналов можно настроить режим, при котором один ваучер выделяется не на строку, а на все строки с одинаковой датой . Для этого случая - гипотеза о сопоставимости времени выполнения count() и загрузки одной строки не срабатывает...
Да и в режиме Номенклатура+дата, выделение нового ваучера происходит только если в очередной строке номенклатура отличается от номенклатуры в предыдущей строке. Если у тебя, скажем, списывается много одинаковой номенклатуры с разными серийными номерами - гипотеза тоже не срабатывает.
Да, когда выделяется один ваучер на весь журнал, то может быть сотня тысяч записей, все с одним и тем же значением полей в индексе.

И для выбора одной строки скорее всего будет использоваться кэш, поэтому сильно снижается время на выборку.

Только что знакомый мой попробовал симулировать данную ситуацию, создав табличку, соответствующий индекс, т.д. Кол-во записей - 100 тысяч.
Для выбора одной записи потребовалось:
CPU time: 0 ms, Elapsed time: 0 ms
Для выполнения подсчета записей потребовалось:
CPU time: 16 ms, Elapsed time: 100 ms

Результат, соответственно, таков, что время выбора одной записи лучше в 100 раз (на самом деле, в бесконечность, но кто считает )

P.S. Расчет был с использованием индекса по integer полю. Для индекса по нескольким полям, тем более строковым, разница будет еще больше.
Старый 11.02.2010, 16:55   #13  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
практически я уже переписал методы на всех этих таблицах, как учили в школе.

интересно, много ли ещё таких мест к оптимизации? можно их как-то все автоматически найти?
__________________
Felix nihil admirari
Старый 12.02.2010, 15:01   #14  
AraraT® is offline
AraraT®
Участник
1C
 
158 / 106 (4) +++++
Регистрация: 13.01.2006
Адрес: Республика Татарстан, г. Казань
Цитата:
Сообщение от kashperuk Посмотреть сообщение
AraraT, видимо, имеет ввиду, что когда создаются строки автоматом по всему номенклатурному справочнику, то по многим строкам разница может получиться нулевая. Особенно строки, которых на складе нет (количество 0).
Такие строки и удаляются
Совершенно верно, именно это я и собирался сказать.
Теги
inventjournal, оптимизация, производительность, запрос (query)

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
DAX 40 Запрос при удалении записи f18 DAX: Программирование 2 29.12.2007 14:57
Копирование строк из InventJournalTrans в SalesLine Petruccio DAX: Программирование 11 29.09.2006 11:40
InventJournalTrans DreamCreator DAX: Программирование 7 14.12.2004 14:48
Почему в InventJournalTrans поле linenum вещественного типа?! ATimTim DAX: Программирование 7 17.06.2004 17:35
Не записыватся себестоимость в InventJournaltrans sk45 DAX: Функционал 33 29.08.2003 19:30
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 04:37.