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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.11.2008, 18:30   #1  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
! Оптимизация кода с LedgerTrans
Есть в Axapte 3 SP6 class LedgerRRGOperationBalanceTotal_RU метод
X++:
public AmountMST calc()
{
    AmountMST   sumTmp, balanceAmountMST;

    balanceAmountMST = 0;

    if (m_PEriodType == LedgerRRGBalancePeriodType_RU::Incoming)
        m_CalculateDate -=  1;

    while select  m_AccountList
    outer join    m_LedgerTrans
        where m_LedgerTrans.TransDate  <= m_CalculateDate          &&
              m_AccountList.AccountNum == m_LedgerTrans.AccountNum &&
              m_LedgerTrans.PeriodCode == PeriodCode::Regular
    {
        if (this.checkTransaction(m_LedgerTrans.TransType,
                                  m_LedgerTrans.OperationsTax,
                                  m_LedgerTrans.Correct,
                                  m_LedgerTrans.Dimension,
                                  ''))
        {
            if (m_currencyForCalc == LedgerRRGCurrencyForCalc_RU::AmountMST)
            {
                sumTmp = m_LedgerTrans.AmountMST;
            }
            else
            {
                sumTmp = m_LedgerTrans.AmountMSTSecond;
            }

            balanceAmountMST    += (m_AccountList.ReverseSign ? (-1) : 1) * sumTmp;
        }
    }

    return  balanceAmountMST;
}
Как его можно оптимизировать? Ощутимо долго цикл пробегается по LedgerTrans, да при этом еще вызывает postLoad каждый раз.
Старый 06.11.2008, 19:05   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Poleax Посмотреть сообщение
Как его можно оптимизировать? Ощутимо долго цикл пробегается по LedgerTrans, да при этом еще вызывает postLoad каждый раз.
Во-первых, избавиться от outer join.
Во-вторых, прекратить извращение с суммированием от начала времен и использовать промежуточные итоги из LedgerBalancesDimTrans.
__________________
полезное на axForum, github, vk, coub.
Старый 06.11.2008, 19:10   #3  
raz is offline
raz
NavAx
Аватар для raz
NavAx Club
Лучший по профессии 2014
Лучший по профессии 2009
 
1,494 / 1065 (38) ++++++++
Регистрация: 22.07.2003
Адрес: МО
В-третьих, использовать sum() и group by.

В-четвертых, перенести генератор из DAX 4.
За это сообщение автора поблагодарили: gl00mie (2).
Старый 06.11.2008, 19:20   #4  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
mazzy по вашему outer joint тут вообще не нужен?
raz
Цитата:
В-четвертых, перенести генератор из DAX 4.
вы уверены, что можно его из 4 в 3 перенести? Есть реализация?
Старый 06.11.2008, 19:25   #5  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
На сколько необходим вызов табличного метода postLoad() при каждом обращении к LedgerTrans ?
Деактивировать его можно или не нужно?
Старый 06.11.2008, 19:49   #6  
raz is offline
raz
NavAx
Аватар для raz
NavAx Club
Лучший по профессии 2014
Лучший по профессии 2009
 
1,494 / 1065 (38) ++++++++
Регистрация: 22.07.2003
Адрес: МО
X++:
public AmountMST calc()
{
    AmountMST   sumTmp, balanceAmountMST;

    balanceAmountMST = 0;

    if (m_PEriodType == LedgerRRGBalancePeriodType_RU::Incoming)
        m_CalculateDate -=  1;

    while select  m_AccountList
    while select  sum(AmountMST), sum(AmountMSTSecond) from m_LedgerTrans
        group by TransType, OperationsTax, Correct, Dimension
        where m_LedgerTrans.TransDate  <= m_CalculateDate          &&
              m_LedgerTrans.AccountNum == m_AccountList.AccountNum &&
              m_LedgerTrans.PeriodCode == PeriodCode::Regular
    {
        if (this.checkTransaction(m_LedgerTrans.TransType,
                                  m_LedgerTrans.OperationsTax,
                                  m_LedgerTrans.Correct,
                                  m_LedgerTrans.Dimension,
                                  ''))
        {
            if (m_currencyForCalc == LedgerRRGCurrencyForCalc_RU::AmountMST)
            {
                sumTmp = m_LedgerTrans.AmountMST;
            }
            else
            {
                sumTmp = m_LedgerTrans.AmountMSTSecond;
            }

            balanceAmountMST    += (m_AccountList.ReverseSign ? (-1) : 1) * sumTmp;
        }
    }

    return  balanceAmountMST;
}
Цитата:
вы уверены, что можно его из 4 в 3 перенести?
абсолютно уверен
За это сообщение автора поблагодарили: Poleax (2).
Старый 06.11.2008, 20:15   #7  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от Poleax Посмотреть сообщение
mazzy по вашему outer joint тут вообще не нужен?
Да.
__________________
полезное на axForum, github, vk, coub.
Старый 06.11.2008, 20:54   #8  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от raz Посмотреть сообщение
where m_LedgerTrans.TransDate <= m_CalculateDate &&
Это конечно, да...
Но снова суммирование идет от начала времен.

Разберитесь как суммирует класс LedgerBalanceDim_CurrentMST и все семейство LedgerBalance*
__________________
полезное на axForum, github, vk, coub.
Старый 06.11.2008, 21:01   #9  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Цитата:
Сообщение от raz
В-четвертых, перенести генератор из DAX 4.
Что верно, то верно.

Там одно только сокращение выбираемых для каждой записи полей само по себе уже даст ощутимый прирост производительности.

Но в 4.0 был реализован комплекс мер по повышению производительности. Глупо было бы не перенести. Тем более, что там функционал развивают.
__________________
С уважением,
glibs®
Старый 07.11.2008, 09:04   #10  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от glibs Посмотреть сообщение
Там одно только сокращение выбираемых для каждой записи полей само по себе уже даст ощутимый прирост производительности.
Это да.
Но гораздо больший прирост даст отсутствие перехваченного метода postload, а следовательно запрос будет целиком исполняться на SQL-сервере
__________________
полезное на axForum, github, vk, coub.
Старый 07.11.2008, 09:16   #11  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Цитата:
Сообщение от mazzy
...
запрос будет целиком исполняться на SQL-сервере
...
А что в данном контексте нужно понимать под термином "запрос"?
__________________
С уважением,
glibs®
Старый 07.11.2008, 09:31   #12  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от glibs Посмотреть сообщение
А что в данном контексте нужно понимать под термином "запрос"?
текстовая строка "Select <Бла-бла-бла> from <Бла-бла-бла> ...", которая выполняется НА СЕРВЕРЕ.

поскольку у таблицы LedgerTrans переопределен метод postLoad, то умная Аксапта не посылает SQL-серверу запрос с просьбой посуммировать, а выбирает все записи по одной, применяет к каждой метод postLoad и суммирует сама.

Поэтому для таблиц с перехваченным postLoad гораздо важнее сократить объем выборки, нежели делать агрегирование (raz, к великому сожалению для таблицы LeagerTrans ваш совет не очень помогает. Вот для других таблиц - да, очень полезный совет).


Так вот. Русские отчеты написаны неправильно. Они не учитывают "особенность" таблицы LedgerTrans и суммируют "от начала времен". Что приводит к выборке в Аксапту каждой проводки из LedgerTrans, которая попадает в условие.

Еще раз советую посмотреть как с этим вопросом справились в буржуйских финансовых отчетах. В буржуйских из LedgerTrans никогда не выбирается больше финансового периода - Большинство данных берется из промежуточных итогов. (надо также помнить, что финансовый период безболезненно можно разбить на несколько в случае чего)
__________________
полезное на axForum, github, vk, coub.
Старый 07.11.2008, 09:43   #13  
raz is offline
raz
NavAx
Аватар для raz
NavAx Club
Лучший по профессии 2014
Лучший по профессии 2009
 
1,494 / 1065 (38) ++++++++
Регистрация: 22.07.2003
Адрес: МО
Цитата:
Сообщение от mazzy Посмотреть сообщение
Поэтому для таблиц с перехваченным postLoad гораздо важнее сократить объем выборки, нежели делать агрегирование (raz, к великому сожалению для таблицы LeagerTrans ваш совет не очень помогает. Вот для других таблиц - да, очень полезный совет).
спорить не буду, но вот такой job:
X++:
static void Job1(Args _args)
{
    ledgertrans     lt;
    ;
    select sum(amountmst) from lt where lt.AccountNum == "zzz";
    print(lt.AmountMST);
    pause;
}
дал такой эффект (количество записей в LedgerTrans 8933031 количество суммируемых записей 438868)
Миниатюры
Нажмите на изображение для увеличения
Название: job.jpg
Просмотров: 386
Размер:	97.2 Кб
ID:	3879  

Последний раз редактировалось raz; 07.11.2008 в 09:48.
Старый 07.11.2008, 09:47   #14  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Я тоже не буду спорить ...

Но если поставить брякпоинт в методе .postLoad(), то с помощью дебагера и счетных палочек можно убедиться, что этот вражеский метод вызывается для результата GROUP BY, а не для каждого LedgerTrans в отдельности.
__________________
С уважением,
glibs®
За это сообщение автора поблагодарили: mazzy (5).
Старый 07.11.2008, 09:51   #15  
raz is offline
raz
NavAx
Аватар для raz
NavAx Club
Лучший по профессии 2014
Лучший по профессии 2009
 
1,494 / 1065 (38) ++++++++
Регистрация: 22.07.2003
Адрес: МО
Цитата:
Сообщение от glibs Посмотреть сообщение
Я тоже не буду спорить ...

Но если поставить брякпоинт в методе .postLoad(), то с помощью дебагера и счетных палочек можно убедиться, что этот вражеский метод вызывается для результата GROUP BY, а не для каждого LedgerTrans в отдельности.
Таким образом суммирование и группировка дают колоссальный эффект...
За это сообщение автора поблагодарили: mazzy (10).
Старый 07.11.2008, 10:03   #16  
glibs is offline
glibs
Member
Сотрудники компании It Box
Most Valuable Professional
Лучший по профессии 2011
Лучший по профессии 2009
 
4,942 / 911 (40) +++++++
Регистрация: 10.06.2002
Адрес: I am from Kyiv, Ukraine. Now I am in Moscow. For private contacts: glibs@hotmail.com
Вообще, тема относительно русских финотчетов уже была раскрыта...

Генератор финансовых отчётов

И даже обновление потом вышло.
__________________
С уважением,
glibs®
За это сообщение автора поблагодарили: Poleax (2).
Старый 07.11.2008, 12:13   #17  
Poleax is offline
Poleax
Модератор
Аватар для Poleax
MCP
MCBMSS
Злыдни
 
1,353 / 595 (22) +++++++
Регистрация: 17.02.2005
Адрес: msk
Записей в блоге: 34
Какая интересная большая тема получилась.
Raz спасибо, твой код ускорил вывод отчета, с 3 часов до 12 минут.
P.S. Данные в отчетах одинаковые

glibs
Генератор финансовых отчётов
Цитата:
2. Не то, чтобы радикально, но факт. Как это ни банально, но создание кластерных индексов на таблицах LedgerRRGAccountInterval_RU, LedgerRRGCellTable_RU, LedgerRRGDimensionInterval_RU, LedgerRRGOffsetAccountInterval_RU, LedgerRRGOperationTable_RU повышает скорость выборки данных для отчета. Еще раз повторю, что не радикально. Можно сказать даже не существенно на фоне вышеописанного. Ну и поставить EntireTable кэш на LedgerRRGReportTable_RU равно как и группу таблиц Group какой-нибудь вместо Misc тоже не помешает.
Уточнить можно точный список полей для кластерного индекса, для каждой таблицы (LedgerRRGAccountInterval_RU, LedgerRRGCellTable_RU, LedgerRRGDimensionInterval_RU, LedgerRRGOffsetAccountInterval_RU, LedgerRRGOperationTable_RU )?

Последний раз редактировалось Poleax; 07.11.2008 в 12:25.
Старый 07.11.2008, 12:14   #18  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от raz Посмотреть сообщение
спорить не буду, но...
Цитата:
Сообщение от glibs Посмотреть сообщение
Я тоже не буду спорить ...
Все бы так "не спорили"

Я тут было хотел съехидничать по поводу упрощения задачи, про то, что в изначальном методе были офигительные Group by... Но просто проверил. ax3.0sp6, ax4.0sp2, ax2009. Результат одинаковый:

Действительно группирует на сервере, невзирая на перекрытый метод PostLoad. Офигеть!
Нажмите на изображение для увеличения
Название: 1.jpg
Просмотров: 335
Размер:	76.9 Кб
ID:	3880

X++:
static void Job7(Args _args)
{
    ledgertrans     lt;
    ;
    while select sum(amountmst) from lt
    group by AccountNum, TransDate, PeriodCode, TransType, OperationsTax, Correct, Dimension
    where lt.AccountNum == "51.010"
    {
        print(lt.AmountMST);
    }
}
"Но ведь был же сарайчик" (С)...
Интересно, когда поменяли?
Ладно, спишем на мой старческий маразм.

Спасибо вам огромное.

Цитата:
Сообщение от raz Посмотреть сообщение
Таким образом суммирование и группировка дают колоссальный эффект...
Да.
raz, ты прав!
__________________
полезное на axForum, github, vk, coub.
Старый 07.11.2008, 12:32   #19  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от raz Посмотреть сообщение
Таким образом суммирование и группировка дают колоссальный эффект...
Но тем не менее, это не повод заставлять SQL суммировать от начала времен
Выборку все равно нужно сокращать.
__________________
полезное на axForum, github, vk, coub.
Теги
ledgertrans, отчет, производительность, ax3.0, финансовые движения

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Оптимизация кода exodus DAX: Программирование 11 07.11.2007 13:16
Как для ГК операции в LedgerTrans найти соответствующую операцию в VendTrans? romulis DAX: Программирование 20 29.08.2006 14:10
При в таблице LedgerTrans не заполняется поле vasiliy DAX: Программирование 5 08.04.2005 11:43
проблема с настройкой штрихового кода Nic DAX: Функционал 4 27.12.2004 09:04
Оптимизация кода X++ Владимир Максимов DAX: Программирование 8 19.01.2004 15:24

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

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

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