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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 23.04.2011, 00:51   #1  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
оптимизация запроса статистики по клиенту
последние трое суток провёл в занимательном чтении топиков с названиями вида "оптимизация запроса", но так и не нашёл ответа на свой вопрос. точнее, на несколько. озвучу их, плавно переходя от частного к общему. (дело происходит в AX2009+SQL2005)

на форме таблицы клиентов есть кнопочка запросов, среди которых есть "статистика". в нём отображается общее количество счетов-фактуров и проч. в заданных (5) периодах времени. так вот этот запрос формируется на одном и том же клиенте иной раз до 15 минут. посольку заказчик любит "запущать" это дело по нескольку раз на дню, его это сильно печалит.

судя по информации из таблицы логов sql в ax, основные "затыки" происходят в методе calcTotals в двух местах: там где идёт while select custTrans exists join ledgerTrans и ещё более вложенной конструкции.

1. можно ли как-то переписать данный запрос путём указания индексов, указания, какие именно поля нужно выбирать и проч?

2. нужно ли "шаманить" на sql сервере путём настроек или увеличения мощностей.

3. как в общем случае определять точку приложения усилий по решению подобных проблем с производительностью: код, скл-сервер, железо, архитектура? я понимаю, что нужно комплексно подходить, но меня интересует некий "алгоритм", который используется уважаемыми коллегами в их повседневной практике.


код "узкого места" класса:

X++:
    while select custTrans
        where custTrans.AccountNum          == custTable.AccountNum                     &&
              custTrans.TransDate           >= tmpStatPer.StartDate                     &&
              custTrans.TransDate           <= tmpStatPer.EndDate                       &&
//              custTrans.amountCur           <  0                                        &&
              custTrans.Invoice             == ''
        exists join ledgerTrans
            where ledgerTrans.TransDate     == custTrans.TransDate                      &&
                  ledgerTrans.Voucher       == custTrans.Voucher                        &&
                  (ledgerTrans.Posting      == LedgerPostingType::CustPayment   ||
                   ledgerTrans.Posting      == LedgerPostingType::CustBalance)
    {
        bankAccountTrans = BankAccountTrans::find(ledgerTrans.PaymReference);

        if (!bankAccountTrans || bankAccountTrans.BankTransType != BankParameters::find().nsfTransactionType)
        {
            if (custTrans.AmountCur <  0)
            {
                tmpStatPer.PaymQty ++;
            }
            else
            {
                tmpStatPer.PaymQty --;
            }

            tmpStatPer.PaymTotal        += -custTrans.AmountMST;

            while select custSettlement
                where custSettlement.TransRecId     == custTrans.RecId &&
                      custSettlement.OffsetTransVoucher
            {
                while select crossCompany custOffsetTrans
                    where custOffsetTrans.AccountNum     == custSettlement.OffsetAccountNum     &&
                          custOffsetTrans.Voucher        == custSettlement.OffsetTransVoucher   &&
                          custOffsetTrans.DataAreaId     == custSettlement.OffsetCompany        &&
                          custOffsetTrans.Invoice
                {
                    numOfInvoices               ++;
                    tmpStatPer.AveragePaymDays  += (custTrans.TransDate- custOffsetTrans.TransDate);
                }
            }
        }
    }
большое спасибо!
__________________
Felix nihil admirari

Последний раз редактировалось wojzeh; 27.10.2019 в 19:35.
Старый 23.04.2011, 08:12   #2  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Судя по
X++:
exists join ledgerTrans
и вызову в цикле
X++:
bankAccountTrans = BankAccountTrans::find(ledgerTrans.PaymReference);
сам запрос построен неправильно. exists join не возвращает данные в табличную переменную. У вас всегда будет ledgerTrans.PaymReference == "". Надо делать через простой join с выборкой только PaymReference, т.е.
X++:
 join PaymReference from ledgerTrans
__________________
Axapta v.3.0 sp5 kr2
За это сообщение автора поблагодарили: wojzeh (1).
Старый 26.04.2011, 05:08   #3  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
а ларчик просто открывался...

большое спасибо! видимо, зря понадеялся на разработчиков микрософт.
__________________
Felix nihil admirari
Теги
оптимизация

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Оптимизация запроса - ranges kashperuk DAX: Программирование 13 31.01.2011 20:19
как подсчитать баланс по клиенту kitty DAX: Программирование 2 27.02.2008 17:38
Оптимизация запроса oleg_e DAX: Программирование 16 11.01.2008 10:22
Опять оптимизация запроса KpecT DAX: Программирование 3 02.11.2007 14:41
Оптимизация запроса Янка DAX: Программирование 1 27.04.2006 08:37
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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