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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 02.03.2013, 15:29   #1  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
DAX4: генератор финснсовой отчетности, выборка оборотов по корреспонденции счетов
Ни для кого не является секретом, что при настройке в ГФО выборки оборотов по счетам в корреспонденции с другими счетами работа ГФО становится не очень быстрой.
Раньше мы мирились с данной особенностью, но, в последнее время, пользователей стали эти особенности раздражать, пришлось искать методы оптимизации.
Формирование запроса на выборку в условиях корреспонденции производится в методе initQuery класса LedgerRRGOp_Ledger_Trans_RU. В DAX4 у нас загружены практически все изменения, существовавшие на момент прекращения поддержки DAX4. Ветка, которая относится к формированию запроса по корреспонденции
X++:
        case LedgerRRGOperationType_RU::TurnoverInCorr:
        case LedgerRRGOperationType_RU::TurnoverInCorrDebit:
        case LedgerRRGOperationType_RU::TurnoverInCorrCredit:
В стандарте выглядит так:
X++:
            this.addTransDateRange(parms.transDatePeriodFilter(baseDate));
            this.addRange(fieldnum(LedgerTrans, BondBatch_RU), SysQuery::valueNotEmptyString());
            this.addRange(fieldnum(LedgerTrans, BondBatchTrans_RU), SysQuery::valueNotEmptyString());
            offsetQueryBuildDatasource = queryBuildDataSource.addDataSource(tablenum(LedgerTrans));
            offsetQueryBuildDatasource.joinMode(JoinMode::ExistsJoin);
            offsetQueryBuildDatasource.addLink(fieldnum(LedgerTrans, TransDate), fieldnum(LedgerTrans, TransDate));
            offsetQueryBuildDatasource.addLink(fieldnum(LedgerTrans, Voucher), fieldnum(LedgerTrans, Voucher));
            offsetQueryBuildDatasource.addLink(fieldnum(LedgerTrans, BondBatch_RU), fieldnum(LedgerTrans, BondBatch_RU));
            offsetQueryBuildDatasource.addLink(fieldnum(LedgerTrans, BondBatchTrans_RU), fieldnum(LedgerTrans, BondBatchTrans_RU));
            offsetQueryBuildDatasource.addRange(fieldnum(LedgerTrans, AccountNum)).value(parms.offsetAccountFilter());
            offsetQueryBuildDatasource.addRange(fieldnum(LedgerTrans, PeriodCode)).value(SysQuery::value(PeriodCode::Regular));
            offsetQueryBuildDatasource.addRange(fieldnum(LedgerTrans, Crediting)).value(#CreditingQueryValue);
После оптимизации эта ветка выглядит так:
X++:
            this.addTransDateRange(parms.transDatePeriodFilter());
            this.addRange(fieldnum(LedgerTrans, BondBatch_RU), SysQuery::valueNotEmptyString());
            this.addRange(fieldnum(LedgerTrans, BondBatchTrans_RU), SysQuery::valueNotEmptyString());
            offsetQueryBuildDatasource = queryBuildDataSource.addDataSource(tablenum(LedgerTrans));

            // Изменил соединение с Exist на Inner с группировкой по RecId, убрал лишние условия соединения
            // Добавил подсказки на Query по порядку обработки таблиц запроса
            offsetQueryBuildDatasource.joinMode(JoinMode::InnerJoin);
            offsetQueryBuildDatasource.addSelectionField(fieldNum(LedgerTrans, RecId), SelectionField::Min);
            offsetQueryBuildDatasource.orderMode(OrderMode::GroupBy);

            query.forceSelectOrder(true);
            query.forceNestedLoop(true);

            offsetQueryBuildDatasource.addLink(fieldnum(LedgerTrans, BondBatch_RU), fieldnum(LedgerTrans, BondBatch_RU));
            offsetQueryBuildDatasource.addLink(fieldnum(LedgerTrans, BondBatchTrans_RU), fieldnum(LedgerTrans, BondBatchTrans_RU));

            offsetQueryBuildDatasource.addRange(fieldnum(LedgerTrans, AccountNum)).value(parms.offsetAccountFilter());
            offsetQueryBuildDatasource.addRange(fieldnum(LedgerTrans, PeriodCode)).value(SysQuery::value(PeriodCode::Regular));
            offsetQueryBuildDatasource.addRange(fieldnum(LedgerTrans, Crediting)).value(#CreditingQueryValue);
Как видно из приведенного кода, выполнены следующие изменения:
  • Изменен тип соединения и, на всякий случай, в связаннойм запросе сделана группировка.
  • Оптимизатору дана подсказка по поводу порядка выборки данных таблиц.
  • Убраны лишние условия соединения.
Мониторинг запросов в MS SQL показал:
  • В исходном варианте в случае выборки по 3-5 счетам главной таблицы и 2-3 счетам корреспонденции среднее время выборки по одной строке ГФО составляло 15000-26000 миллисекунд.
  • После изменения типа соединения среднее время составляло 2000 - 5000 миллисекунд.
  • После добавления подсказки оптимизатору среднее время сократилось до 90-150 миллисекунд.
В итоге время формирования отчета вместо 30-90 минут стало в районе 5-10 минут. Вроде бы проблему решили, но переносить эти изменения в рабочую базу как-то страшно.
В настройке наших отчетов данные до изменения и после изменения выдаются одни и те же, только кратно ускорилась работа отчета. Боюсь, что я что-то не учел и на других настройках ГФО просто начнет выдавать неправильные данные.
Просьба, если у кого-либо будет время, проанализировать эти изменения с точки зрения того, что может быть нарушено.

Последний раз редактировалось Raven Melancholic; 02.03.2013 в 15:33.
Старый 02.03.2013, 17:11   #2  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Изменен тип соединения и, на всякий случай, в связаннойм запросе сделана группировка.
Или я чего-то не понял или... Я все время был уверен что в аксапте нельзя приджойнить сгруппированную таблицу, а можно только сгруппировать результат джойна.
За это сообщение автора поблагодарили: Raven Melancholic (2).
Старый 03.03.2013, 12:07   #3  
Raven Melancholic is offline
Raven Melancholic
Участник
Аватар для Raven Melancholic
Самостоятельные клиенты AX
Лучший по профессии 2015
 
2,164 / 1293 (48) ++++++++
Регистрация: 21.03.2005
Адрес: Москва-Петушки
Да, естественно, что группируются результаты всего запроса - я неудачно выразился.
Просто ,если вместо exists делать inner и прямо не указать какую-то группировку по приджоиненной таблице, то запрос, отправляемый на сервер, на мой взгляд, выглядит как-то неэстетично.
На самом деле, связь по корреспонденции вполне однозначна - 1:1 (либо я что-то не знаю и не видел других вариантов). Поэтому вроде бы можно было и без группировки по RecId, но тут просто сила привычки.
Старый 03.03.2013, 13:04   #4  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от Raven Melancholic Посмотреть сообщение
Да, естественно, что группируются результаты всего запроса - я неудачно выразился.
Это значит, что запрос выбирает из таблиц (и из подчинённой и из главной) значения только тех столбцов, которые включены в группировку, а также по которым указаны агрегирующие функции. А в стандарте запрос выбирал все имеющиеся в таблицах поля? Или там изначально была группировка? Меня собственно именно этот момент смущает. Не теряются ли относительно стандарта значения полей в запросе?
Теги
генератор финансовых отчетов

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Контроль корреспонденции счетов в AX 4.0 sp2 Alexx7 DAX: Функционал 7 10.06.2011 16:17
Еще раз про переименование счетов (DAX4) Qaz Qwerty DAX: Программирование 5 18.04.2011 23:21
DAX4 функционал электронной отчетности: есть ли для Казахстана? Raven Melancholic DAX: Функционал 13 09.03.2011 15:45
запрет корреспонденции счетов Solma DAX: Функционал 10 24.02.2011 16:37
Сальдо активно-пассивных счетов в Российской финансовой отчетности KatyN DAX: Функционал 48 28.08.2006 17:57
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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