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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.09.2009, 09:34   #1  
Alexanderrrr is offline
Alexanderrrr
Участник
Аватар для Alexanderrrr
 
54 / 19 (1) ++
Регистрация: 06.03.2009
Адрес: Саратов
Проблема с LedgerJournalTrans
Доброго времени суток, уважаемые жители axforuma!

Возможно мой вопрос покажется глупым.

У нас существует отчет "Оплата по группам финансирования", выбирающий данные из таблиц Custtrans, CustInvoiceJour и LedgerJournalTrans (Axapta 3.0 SP5). Работал он работал, и вот однажды утром стал работать гораздо медленнее. Своими разработками мы этот отчет не трогали. Включив мониторинг запросов, выяснил, что очень долго производится выборка из LedgerJournalTrans. Сделав реиндексацию по всем индексам этой таблицы, временно решил проблему. Но к этому вопросу постоянно приходится обращаться.


Привожу код, выбирающий данные из LedgerJournalTrans в темповую таблицу, используюмую в отчете.

Код:
void insertTmpFromLedgerJournalTrans()
{
    QueryRun            qrLedgerJour;
    RContractTable      qContractTable;
    LedgerJournalTrans  qLedgerTrans;
    LedgerJournalTrans  ledgerTrans;
    LedgerJournalTable  ledgerTable;
    CustSettlement      custSettlement;
    CustSettlement      settlement;
    CustTrans           custTrans, custTransSelect;
    ;


    qrLedgerJour = new QueryRun(queryStr(GroupFinancLedgerJournalTrans));

    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,TransDate)).value(queryRange(dateFrom,dateTo));
    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,AmountCurCredit)).value("!=0");
    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,AccountType)).value(enum2str(LedgerJournalACType::Cust));
    qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldnum(RContractTable,RContractPartnerType)).value(enum2str(RContractPartnerType::Cust));

    if (rangeDimension)
        qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldId2ext(fieldnum(LedgerJournalTrans, Dimension),2)).value(rangeDimension);
    if (rangeGroupFinanc)
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldnum(RContractTable,GroupFinancId)).value(rangeGroupFinanc);
    if (accountNum)
        qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldNum(LedgerJournalTrans,AccountNum)).value(accountNum);
    if (contractAccount)
    {
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractCode)).value(contractCode);
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractAccount)).value(contractAccount);
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractPartnerCode)).value(accountNum);
    }

    while (qrLedgerJour.next())
    {
        qLedgerTrans    = qrLedgerJour.get(tableNum(LedgerJournalTrans));
        qContractTable  = qrLedgerJour.get(tableNum(RContractTable));

        while select RecId, budget, JournalNum, Voucher, AccountNum, AmountCurCredit from ledgerTrans
            where ledgerTrans.RecId        == qLedgerTrans.RecId
        join JournalNum, Posted, JournalType from ledgerTable
            index hint PostedJournalNumIdx
            where ledgerTable.JournalNum    == ledgerTrans.JournalNum   &&
                  ledgerTable.Posted        == NoYes::Yes
        {

            //select firstonly Voucher,AccountNum,SettleAmountCur,TransDate,AmountCur from custTrans
            while select Voucher, AccountNum, SettleAmountCur, TransDate, AmountCur from custTrans
                index hint AccountDateIdx
                where custTrans.Voucher     == ledgerTrans.Voucher  &&
                      custTrans.AccountNum  == ledgerTrans.AccountNum
            {

                if (custTrans.AmountCur - custTrans.SettleAmountCur != 0)
                {
                    tmpTable.clear();

                    if (ledgerTrans.budget == NoYes::Yes)
                    {
                        tmpTable.BPayCurrent    = custTrans.AmountCur - custTrans.SettleAmountCur;
                        tmpTable.PayCurrent     = 0;
                    }
                    else
                    {
                        tmpTable.PayCurrent     = custTrans.AmountCur - custTrans.SettleAmountCur;
                        tmpTable.BPayCurrent    = 0;
                    }
                    tmpTable.GroupFinancName    = ICLGroupsFinancTable::find(qContractTable.GroupFinancId).GroupFinancName;
                    tmpTable.AccountNum         = qLedgerTrans.AccountNum;
                    tmpTable.AccountName        = CustTable::find(qLedgerTrans.AccountNum).NameAlias;
                    tmpTable.ContractNumberDate = qContractTable.contractNumberDate;
                    tmpTable.Voucher            = qLedgerTrans.Voucher;
                    tmpTable.AddQty             = 0;
                    tmpTable.AddAmount          = 0;
                    tmpTable.DebtBeginPeriod    = 0;
                    tmpTable.Advance            = NoYes::Yes;
                    tmpTable.CurrentPayTotal    = tmpTable.BPayCurrent + tmpTable.PayCurrent;
                    tmpTable.PayPeriodTotal     = tmpTable.BPay + tmpTable.Pay + tmpTable.CurrentPayTotal;
                    tmpTable.CurrentDebt        = tmpTable.AddAmount + tmpTable.CurrentPayTotal;
                    tmpTable.EndDebt            = tmpTable.DebtBeginPeriod + tmpTable.AddAmount + tmpTable.PayPeriodTotal/*CurrentPayTotal*/;

                    tmpTable.insert();
                }
                while select OffsetTransVoucher, AccountNum, OffsetRecid, TransRecId, SettleAmountCur from custSettlement
                    index hint OffsetVoucherIdx
                    //where custSettlement.OffsetTransVoucher == ledgerTrans.Voucher      &&
                    //      custSettlement.AccountNum         == ledgerTrans.AccountNum   &&
                    where custSettlement.TransRecId    == custTrans.RecId      &&
                          custSettlement.AccountNum    == custTrans.AccountNum &&
                          custSettlement.CanBeReversed == NoYes::Yes

                {
                   select firstonly Voucher, AccountNum, SettleAmountCur, TransDate from custTransSelect
                        index hint AccountDateIdx
                        //where custTransSelect.Voucher     == settlement.OffsetTransVoucher  &&
                        where custTransSelect.RecId      == custSettlement.OffsetRecid  &&
                              custTransSelect.AccountNum == custSettlement.AccountNum;

                    tmpTable.clear();

                    if (ledgerTrans.budget == NoYes::Yes)
                    {
                        if (custTransSelect.TransDate >= dateFrom)
                        {
                            tmpTable.BPayCurrent    = custSettlement.SettleAmountCur;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = 0;
                        }
                        else
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = custSettlement.SettleAmountCur;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = 0;
                        }
                    }
                    else
                    {
                        if (custTransSelect.TransDate >= dateFrom)
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = custSettlement.SettleAmountCur;
                            tmpTable.Pay            = 0;
                        }
                        else
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = custSettlement.SettleAmountCur;
                        }
                    }

                    tmpTable.GroupFinancName    = ICLGroupsFinancTable::find(qContractTable.GroupFinancId).GroupFinancName;
                    tmpTable.AccountNum         = qLedgerTrans.AccountNum;
                    tmpTable.AccountName        = CustTable::find(qLedgerTrans.AccountNum).NameAlias;
                    tmpTable.ContractNumberDate = qContractTable.contractNumberDate;
                    tmpTable.Voucher            = qLedgerTrans.Voucher;
                    tmpTable.AddQty             = 0;
                    tmpTable.AddAmount          = 0;
                    tmpTable.DebtBeginPeriod    = 0;
                    tmpTable.Advance            = (custTransSelect.TransDate > dateTo ? NoYes::Yes : NoYes::No);NoYes::No;
                    tmpTable.CurrentPayTotal    = tmpTable.BPayCurrent + tmpTable.PayCurrent;
                    tmpTable.PayPeriodTotal     = tmpTable.BPay + tmpTable.Pay + tmpTable.CurrentPayTotal;
                    tmpTable.CurrentDebt        = tmpTable.AddAmount + tmpTable.CurrentPayTotal;
                    tmpTable.EndDebt            = tmpTable.DebtBeginPeriod + tmpTable.AddAmount + tmpTable.PayPeriodTotal/*CurrentPayTotal*/;

                    tmpTable.insert();

                }
           }
        }
    }

}
Не подскажите, в чем может быть дело?
__________________
..в каждой программе есть хотя бы одна ошибка..

Последний раз редактировалось Alexanderrrr; 18.09.2009 в 09:37.
Старый 18.09.2009, 09:49   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
прежде всего: хранить данные в строках журнала - моветон. строки журналов - черновики. строки журналов могут удаляться в любой момент штатным функционалом.

По делу:
насколько я понимаю, у вас в query GroupFinancLedgerJournalTrans используется две таблицы.
вы накладываете условия на поля этих таблиц. Я не знаю как устроены индексы в вашем запросе и в вашем приложении. Но, вообще говоря, под ваши условия не подходит ни один индекс из стандартного функционала. А это значит, что, скорее всего, запрос будет выполняться тупым Table Scan'ом. Со всеми вытекающими последствиями для большой таблицы.

и я бы indexhint проверил... эта штука опасная. потому что зачастую разработчики вставляют его на маленькой базе. А когда база вырастает, то лучше использовать совсем другие индексы...
__________________
полезное на axForum, github, vk, coub.
За это сообщение автора поблагодарили: Gustav (2), Alexanderrrr (1).
Старый 18.09.2009, 10:26   #3  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1234 (44) ++++++++
Регистрация: 11.04.2008
0. Тему бы раздел "Программирование"
1. Какой SQL используете?
2. Посмотреть бы ещё на кверю GroupFinancLedgerJournalTrans, возможно туда можно подцепить JournalNum, тогда от одного цикла можно было бы избавиться - это самый злой момент.
X++:
(while select RecId, budget, JournalNum, Voucher, AccountNum, AmountCurCredit from ledgerTrans
            where ledgerTrans.RecId        == qLedgerTrans.RecId
         join JournalNum, Posted, JournalType from ledgerTable
            index hint PostedJournalNumIdx
            where ledgerTable.JournalNum    == ledgerTrans.JournalNum   &&
                  ledgerTable.Posted        == NoYes::Yes)
А так, что можно попробовать безболезненно:
3. "join ... from ledgerTable" заменить на "exists join ... from ledgerTable"
4. Заменить индекс OffsetVoucherIdx на TransIndex
X++:
while select OffsetTransVoucher, AccountNum, OffsetRecid, TransRecId, SettleAmountCur from custSettlement
                    index hint TransIndex //orig:  index hint OffsetVoucherIdx
                    //where custSettlement.OffsetTransVoucher == ledgerTrans.Voucher      &&
                    //      custSettlement.AccountNum         == ledgerTrans.AccountNum   &&
                    where custSettlement.TransRecId    == custTrans.RecId      &&
                          custSettlement.AccountNum    == custTrans.AccountNum &&
                          custSettlement.CanBeReversed == NoYes::Yes
За это сообщение автора поблагодарили: Alexanderrrr (1).
Старый 18.09.2009, 10:35   #4  
Alexanderrrr is offline
Alexanderrrr
Участник
Аватар для Alexanderrrr
 
54 / 19 (1) ++
Регистрация: 06.03.2009
Адрес: Саратов
Да, в GroupFinancLedgerJournalTrans две таблицы: LedgerJournalTrans и RContractTable, связынные по AccountNum, RContractCodeDebit и RContractAccountDebit.

Цитата:
и я бы indexhint проверил...
index hint проверю, сразу на него подумал и на while select..

Цитата:
Какой SQL используете?
sql 2000 использую.

Цитата:
3. "join ... from ledgerTable" заменить на "exists join ... from ledgerTable"
4. Заменить индекс OffsetVoucherIdx на TransIndex
проверю, отпишусь.
__________________
..в каждой программе есть хотя бы одна ошибка..
Старый 18.09.2009, 10:53   #5  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1234 (44) ++++++++
Регистрация: 11.04.2008
Если SQL 2000, то тут с index hint конечно очень аккуратно нужно быть. Если юзается индекс, то порядок полей в условии нужно подгонять под порядок полей в индексе, по возможности. Если не получается то index вообще лучше убрать.

Не ломая кверю GroupFinancLedgerJournalTrans, попробуйте ещё такой вариант, по-идее будет быстрее

(убрал некрасивый цикл, заменил ledgerTrans на qLedgerTrans везде где используется)

X++:
    QueryRun            qrLedgerJour;
    RContractTable      qContractTable;
    LedgerJournalTrans  qLedgerTrans;
    LedgerJournalTrans  ledgerTrans;
    LedgerJournalTable  ledgerTable;
    CustSettlement      custSettlement;
    CustSettlement      settlement;
    CustTrans           custTrans, custTransSelect;
    ;


    qrLedgerJour = new QueryRun(queryStr(GroupFinancLedgerJournalTrans));

    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,TransDate)).value(queryRange(dateFrom,dateTo));
    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,AmountCurCredit)).value("!=0");
    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,AccountType)).value(enum2str(LedgerJournalACType::Cust));
    qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldnum(RContractTable,RContractPartnerType)).value(enum2str(RContractPartnerType::Cust));

    if (rangeDimension)
        qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldId2ext(fieldnum(LedgerJournalTrans, Dimension),2)).value(rangeDimension);
    if (rangeGroupFinanc)
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldnum(RContractTable,GroupFinancId)).value(rangeGroupFinanc);
    if (accountNum)
        qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldNum(LedgerJournalTrans,AccountNum)).value(accountNum);
    if (contractAccount)
    {
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractCode)).value(contractCode);
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractAccount)).value(contractAccount);
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractPartnerCode)).value(accountNum);
    }

    while (qrLedgerJour.next())
    {
        qLedgerTrans    = qrLedgerJour.get(tableNum(LedgerJournalTrans));
        qContractTable  = qrLedgerJour.get(tableNum(RContractTable));

        // dspic -->
        // orig:
        //while select RecId, budget, JournalNum, Voucher, AccountNum, AmountCurCredit from ledgerTrans
        //    where ledgerTrans.RecId        == qLedgerTrans.RecId
        ///*dspic(*/ exists /*)dpsic*/ join JournalNum, Posted, JournalType from ledgerTable
        //    index hint PostedJournalNumIdx
        //    where ledgerTable.JournalNum    == ledgerTrans.JournalNum   &&
        //          ledgerTable.Posted        == NoYes::Yes
        if (qLedgerTrans.ledgerJournalTable().posted)
        // dspic <--
        {
            select firstonly Voucher,AccountNum,SettleAmountCur,TransDate,AmountCur from custTrans
            while select Voucher, AccountNum, SettleAmountCur, TransDate, AmountCur from custTrans
                index hint AccountDateIdx
//dspic:
                where custTrans.Voucher     == qLedgerTrans.Voucher  && //dspic: ledgerTrans --> qLedgerTrans
                      custTrans.AccountNum  == qLedgerTrans.AccountNum   //dspic: ledgerTrans --> qLedgerTrans
            {

                if (custTrans.AmountCur - custTrans.SettleAmountCur != 0)
                {
                    tmpTable.clear();
//dspic:
                    if (qLedgerTrans.budget == NoYes::Yes) //dspic: ledgerTrans --> qLedgerTrans
                    {
                        tmpTable.BPayCurrent    = custTrans.AmountCur - custTrans.SettleAmountCur;
                        tmpTable.PayCurrent     = 0;
                    }
                    else
                    {
                        tmpTable.PayCurrent     = custTrans.AmountCur - custTrans.SettleAmountCur;
                        tmpTable.BPayCurrent    = 0;
                    }
                    tmpTable.GroupFinancName    = ICLGroupsFinancTable::find(qContractTable.GroupFinancId).GroupFinancName;
                    tmpTable.AccountNum         = qLedgerTrans.AccountNum;
                    tmpTable.AccountName        = CustTable::find(qLedgerTrans.AccountNum).NameAlias;
                    tmpTable.ContractNumberDate = qContractTable.contractNumberDate;
                    tmpTable.Voucher            = qLedgerTrans.Voucher;
                    tmpTable.AddQty             = 0;
                    tmpTable.AddAmount          = 0;
                    tmpTable.DebtBeginPeriod    = 0;
                    tmpTable.Advance            = NoYes::Yes;
                    tmpTable.CurrentPayTotal    = tmpTable.BPayCurrent + tmpTable.PayCurrent;
                    tmpTable.PayPeriodTotal     = tmpTable.BPay + tmpTable.Pay + tmpTable.CurrentPayTotal;
                    tmpTable.CurrentDebt        = tmpTable.AddAmount + tmpTable.CurrentPayTotal;
                    tmpTable.EndDebt            = tmpTable.DebtBeginPeriod + tmpTable.AddAmount + tmpTable.PayPeriodTotal/*CurrentPayTotal*/;

                    tmpTable.insert();
                }
                while select OffsetTransVoucher, AccountNum, OffsetRecid, TransRecId, SettleAmountCur from custSettlement
                    index hint TransIndex //orig:  index hint OffsetVoucherIdx
                    //where custSettlement.OffsetTransVoucher == ledgerTrans.Voucher      &&
                    //      custSettlement.AccountNum         == ledgerTrans.AccountNum   &&
                    where custSettlement.TransRecId    == custTrans.RecId      &&
                          custSettlement.AccountNum    == custTrans.AccountNum &&
                          custSettlement.CanBeReversed == NoYes::Yes

                {
                   select firstonly Voucher, AccountNum, SettleAmountCur, TransDate from custTransSelect
                        index hint AccountDateIdx
                        //where custTransSelect.Voucher     == settlement.OffsetTransVoucher  &&
                        where custTransSelect.RecId      == custSettlement.OffsetRecid  &&
                              custTransSelect.AccountNum == custSettlement.AccountNum;

                    tmpTable.clear();
//dspic:
                    if (qLedgerTrans.budget == NoYes::Yes)  //dspic: ledgerTrans --> qLedgerTrans
                    {
                        if (custTransSelect.TransDate >= dateFrom)
                        {
                            tmpTable.BPayCurrent    = custSettlement.SettleAmountCur;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = 0;
                        }
                        else
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = custSettlement.SettleAmountCur;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = 0;
                        }
                    }
                    else
                    {
                        if (custTransSelect.TransDate >= dateFrom)
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = custSettlement.SettleAmountCur;
                            tmpTable.Pay            = 0;
                        }
                        else
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = custSettlement.SettleAmountCur;
                        }
                    }

                    tmpTable.GroupFinancName    = ICLGroupsFinancTable::find(qContractTable.GroupFinancId).GroupFinancName;
                    tmpTable.AccountNum         = qLedgerTrans.AccountNum;
                    tmpTable.AccountName        = CustTable::find(qLedgerTrans.AccountNum).NameAlias;
                    tmpTable.ContractNumberDate = qContractTable.contractNumberDate;
                    tmpTable.Voucher            = qLedgerTrans.Voucher;
                    tmpTable.AddQty             = 0;
                    tmpTable.AddAmount          = 0;
                    tmpTable.DebtBeginPeriod    = 0;
                    tmpTable.Advance            = (custTransSelect.TransDate > dateTo ? NoYes::Yes : NoYes::No);NoYes::No;
                    tmpTable.CurrentPayTotal    = tmpTable.BPayCurrent + tmpTable.PayCurrent;
                    tmpTable.PayPeriodTotal     = tmpTable.BPay + tmpTable.Pay + tmpTable.CurrentPayTotal;
                    tmpTable.CurrentDebt        = tmpTable.AddAmount + tmpTable.CurrentPayTotal;
                    tmpTable.EndDebt            = tmpTable.DebtBeginPeriod + tmpTable.AddAmount + tmpTable.PayPeriodTotal/*CurrentPayTotal*/;

                    tmpTable.insert();

                }
           }
        }
    }
P.S. Если работать будет быстрее, проверьте все ещё раз внимательно, может что упустил и подломал
За это сообщение автора поблагодарили: mazzy (2).
Старый 18.09.2009, 14:45   #6  
Alexanderrrr is offline
Alexanderrrr
Участник
Аватар для Alexanderrrr
 
54 / 19 (1) ++
Регистрация: 06.03.2009
Адрес: Саратов
да, DSPIC, заметно побыстрее стало..спасибо!

может, чтобы еще убыстрить, попробовать создать новые индексы на LedgerJournalTrans?
__________________
..в каждой программе есть хотя бы одна ошибка..
Старый 18.09.2009, 17:14   #7  
Dron AKA andy is offline
Dron AKA andy
Moderator
 
944 / 253 (10) ++++++
Регистрация: 27.03.2002
Адрес: Москва
Цитата:
Сообщение от DSPIC Посмотреть сообщение
0. Тему бы раздел "Программирование"
Сделано.
__________________
Андрей.
Старый 18.09.2009, 18:07   #8  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
5 копеек
в select по CustTrans добавить условие по TransDate
добавить в запросы forceplaceholders
Старый 18.09.2009, 18:38   #9  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1234 (44) ++++++++
Регистрация: 11.04.2008
1. Ещё в куске
X++:
...
select firstonly Voucher,AccountNum,SettleAmountCur,TransDate,AmountCur from custTrans
            while select Voucher, AccountNum, SettleAmountCur, TransDate, AmountCur from custTrans
                index hint AccountDateIdx
                where custTrans.Voucher     == qLedgerTrans.Voucher  && //dspic: ledgerTrans --> qLedgerTrans
                      custTrans.AccountNum  == qLedgerTrans.AccountNum   //dspic: ledgerTrans --> qLedgerTrans
...
Можно поменять местами порядок полей в условии на:
X++:
...
where custTrans.AccountNum  == qLedgerTrans.AccountNum //dspic: ledgerTrans --> qLedgerTrans
   &&  ustTrans.Voucher     == qLedgerTrans.Voucher  && //dspic: ledgerTrans --> qLedgerTrans
(Это приведет условия в соответствие с индексом)

2. Было бы ещё неплохо в кверю GroupFinancLedgerJournalTrans на самый верхний уровень загнать таблицу LedgerJournalTable (Получится лесенка LedgerJournalTable-->LedgerJournalTrans-->RContractTable), там же наложить условие на Posted=Yes. Возможно, бы работало ещё чуть быстрее. И тогда этот артефакт можно вообще убрать
X++:
if (qLedgerTrans.ledgerJournalTable().posted)
Старый 21.09.2009, 10:44   #10  
Alexanderrrr is offline
Alexanderrrr
Участник
Аватар для Alexanderrrr
 
54 / 19 (1) ++
Регистрация: 06.03.2009
Адрес: Саратов
Так, все сделал, только кверик GroupFinancLedgerJournalTrans не менял. Похоже побыстрее стало, но все же проблема осталась..серьезно задумывается на строчке:

while (qrLedgerJour.next())

похоже кверик нехороший...
__________________
..в каждой программе есть хотя бы одна ошибка..
Старый 21.09.2009, 11:08   #11  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от DSPIC Посмотреть сообщение
1. Ещё в куске
...
Можно поменять местами порядок полей в условии на:
...
Ну вы уж совсем современные БД недооцениваете...

2AlexanderrrrВключите SQL-трассировку, смотрите запрос, план запроса, с которым он выполняется. Можете попробовать привести его здесь.
В SQL-е и его плане часто получше видно, что не так и чего не хватает, чем в Аксапте.

Ну либо сложная кверя и "селяви": старые журналы всё-таки нужно чистить, как уже выше Маззи говорил...
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: Alexanderrrr (1).
Старый 21.09.2009, 11:22   #12  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1234 (44) ++++++++
Регистрация: 11.04.2008
Цитата:
Сообщение от Alexanderrrr Посмотреть сообщение
... только кверик GroupFinancLedgerJournalTrans не менял. Похоже побыстрее стало, но все же проблема осталась..серьезно задумывается на строчке:

while (qrLedgerJour.next())

похоже кверик нехороший...
Всё-таки, я бы попробовал поменять. В запросе нужны только posted транзакции, а в журнале ledgerJournalTable есть индекс по posted. Это бы фильтрануло хороший кусок.

Цитата:
Сообщение от ZVV Посмотреть сообщение
Ну вы уж совсем современные БД недооцениваете...
...
А SQLю 2000 тоже не важен порядок полей? Я думал - это 2005й умеет. (не эксперт в SQL). С другой стороны, хотелось бы вначале добиться совершенства X++, прежде чем спускаться до уровня SQL.
За это сообщение автора поблагодарили: Alexanderrrr (1).
Старый 21.09.2009, 13:38   #13  
Alexanderrrr is offline
Alexanderrrr
Участник
Аватар для Alexanderrrr
 
54 / 19 (1) ++
Регистрация: 06.03.2009
Адрес: Саратов
Вашими "молитвами" все стало просто летать))
+Сделал реиндексацию..работает на ура)

не стал ставить фильтр на query..сравнил по скорости с ним и без него..разницы никакой..

Спасибо всем большое!

и еще..честно говоря не понимаю, зачем здесь forceplaceholders?
http://axapta.mazzy.ru/lib/literals_vs_placeholders/ почитал..
__________________
..в каждой программе есть хотя бы одна ошибка..

Последний раз редактировалось Alexanderrrr; 21.09.2009 в 13:49.
Старый 21.09.2009, 14:15   #14  
DSPIC is offline
DSPIC
Боец
 
1,077 / 1234 (44) ++++++++
Регистрация: 11.04.2008
Цитата:
Сообщение от Alexanderrrr Посмотреть сообщение
Вашими "молитвами" все стало просто летать))
+Сделал реиндексацию..работает на ура)

не стал ставить фильтр на query..сравнил по скорости с ним и без него..разницы никакой..

Спасибо всем большое!

и еще..честно говоря не понимаю, зачем здесь forceplaceholders?
http://axapta.mazzy.ru/lib/literals_vs_placeholders/ почитал..
Отлично! Покажите, запрос, который получился в итоге. И проверьте правильность, не поломали ли чего
Старый 23.09.2009, 13:42   #15  
Alexanderrrr is offline
Alexanderrrr
Участник
Аватар для Alexanderrrr
 
54 / 19 (1) ++
Регистрация: 06.03.2009
Адрес: Саратов
Код:
void insertTmpFromLedgerJournalTrans()
{
   QueryRun            qrLedgerJour;
    RContractTable      qContractTable;
    LedgerJournalTrans  qLedgerTrans;
    LedgerJournalTrans  ledgerTrans;
    LedgerJournalTable  ledgerTable;
    CustSettlement      custSettlement;
    CustSettlement      settlement;
    CustTrans           custTrans, custTransSelect;
    ;


    qrLedgerJour = new QueryRun(queryStr(GroupFinancLedgerJournalTrans));

    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,TransDate)).value(queryRange(dateFrom,dateTo));
    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,AmountCurCredit)).value("!=0");
    qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldnum(LedgerJournalTrans,AccountType)).value(enum2str(LedgerJournalACType::Cust));
    qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldnum(RContractTable,RContractPartnerType)).value(enum2str(RContractPartnerType::Cust));

    if (rangeDimension)
        qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldId2ext(fieldnum(LedgerJournalTrans, Dimension),2)).value(rangeDimension);
    if (rangeGroupFinanc)
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldnum(RContractTable,GroupFinancId)).value(rangeGroupFinanc);
    if (accountNum)
        qrLedgerJour.query().dataSourceTable(tableNum(LedgerJournalTrans)).addRange(fieldNum(LedgerJournalTrans,AccountNum)).value(accountNum);
    if (contractAccount)
    {
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractCode)).value(contractCode);
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractAccount)).value(contractAccount);
        qrLedgerJour.query().dataSourceTable(tableNum(RContractTable)).addRange(fieldNum(RContractTable,RContractPartnerCode)).value(accountNum);
    }

    while (qrLedgerJour.next())
    {
        qLedgerTrans    = qrLedgerJour.get(tableNum(LedgerJournalTrans));
        qContractTable  = qrLedgerJour.get(tableNum(RContractTable));

        if (qLedgerTrans.ledgerJournalTable().posted)
        {
            while select Voucher, AccountNum, SettleAmountCur, TransDate, AmountCur from custTrans
                index hint AccountDateIdx
                where custTrans.AccountNum  == qLedgerTrans.AccountNum &&
                 custTrans.Voucher     == qLedgerTrans.Voucher 
            {

                if (custTrans.AmountCur - custTrans.SettleAmountCur != 0)
                {
                    tmpTable.clear();
                    if (qLedgerTrans.budget == NoYes::Yes) 
                    {
                        tmpTable.BPayCurrent    = custTrans.AmountCur - custTrans.SettleAmountCur;
                        tmpTable.PayCurrent     = 0;
                    }
                    else
                    {
                        tmpTable.PayCurrent     = custTrans.AmountCur - custTrans.SettleAmountCur;
                        tmpTable.BPayCurrent    = 0;
                    }
                    tmpTable.GroupFinancName    = ICLGroupsFinancTable::find(qContractTable.GroupFinancId).GroupFinancName;
                    tmpTable.AccountNum         = qLedgerTrans.AccountNum;
                    tmpTable.AccountName        = CustTable::find(qLedgerTrans.AccountNum).NameAlias;
                    tmpTable.ContractNumberDate = qContractTable.contractNumberDate;
                    tmpTable.Voucher            = qLedgerTrans.Voucher;
                    tmpTable.AddQty             = 0;
                    tmpTable.AddAmount          = 0;
                    tmpTable.DebtBeginPeriod    = 0;
                    tmpTable.Advance            = NoYes::Yes;
                    tmpTable.CurrentPayTotal    = tmpTable.BPayCurrent + tmpTable.PayCurrent;
                    tmpTable.PayPeriodTotal     = tmpTable.BPay + tmpTable.Pay + tmpTable.CurrentPayTotal;
                    tmpTable.CurrentDebt        = tmpTable.AddAmount + tmpTable.CurrentPayTotal;
                    tmpTable.EndDebt            = tmpTable.DebtBeginPeriod + tmpTable.AddAmount + tmpTable.PayPeriodTotal;

                    tmpTable.insert();
                }
                while select OffsetTransVoucher, AccountNum, OffsetRecid, TransRecId, SettleAmountCur from custSettlement
                    index hint TransIndex
                    where custSettlement.TransRecId    == custTrans.RecId      &&
                          custSettlement.AccountNum    == custTrans.AccountNum &&
                          custSettlement.CanBeReversed == NoYes::Yes

                {
                   select firstonly Voucher, AccountNum, SettleAmountCur, TransDate from custTransSelect
                        index hint AccountDateIdx
                        where custTransSelect.RecId      == custSettlement.OffsetRecid  &&
                              custTransSelect.AccountNum == custSettlement.AccountNum;

                    tmpTable.clear();
                    if (qLedgerTrans.budget == NoYes::Yes)  
                    {
                        if (custTransSelect.TransDate >= dateFrom)
                        {
                            tmpTable.BPayCurrent    = custSettlement.SettleAmountCur;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = 0;
                        }
                        else
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = custSettlement.SettleAmountCur;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = 0;
                        }
                    }
                    else
                    {
                        if (custTransSelect.TransDate >= dateFrom)
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = custSettlement.SettleAmountCur;
                            tmpTable.Pay            = 0;
                        }
                        else
                        {
                            tmpTable.BPayCurrent    = 0;
                            tmpTable.BPay           = 0;
                            tmpTable.PayCurrent     = 0;
                            tmpTable.Pay            = custSettlement.SettleAmountCur;
                        }
                    }

                    tmpTable.GroupFinancName    = ICLGroupsFinancTable::find(qContractTable.GroupFinancId).GroupFinancName;
                    tmpTable.AccountNum         = qLedgerTrans.AccountNum;
                    tmpTable.AccountName        = CustTable::find(qLedgerTrans.AccountNum).NameAlias;
                    tmpTable.ContractNumberDate = qContractTable.contractNumberDate;
                    tmpTable.Voucher            = qLedgerTrans.Voucher;
                    tmpTable.AddQty             = 0;
                    tmpTable.AddAmount          = 0;
                    tmpTable.DebtBeginPeriod    = 0;
                    tmpTable.Advance            = (custTransSelect.TransDate > dateTo ? NoYes::Yes : NoYes::No);
                    tmpTable.CurrentPayTotal    = tmpTable.BPayCurrent + tmpTable.PayCurrent;
                    tmpTable.PayPeriodTotal     = tmpTable.BPay + tmpTable.Pay + tmpTable.CurrentPayTotal;
                    tmpTable.CurrentDebt        = tmpTable.AddAmount + tmpTable.CurrentPayTotal;
                    tmpTable.EndDebt            = tmpTable.DebtBeginPeriod + tmpTable.AddAmount + tmpTable.PayPeriodTotal/*CurrentPayTotal*/;

                    tmpTable.insert();

                }
           }
        }
    }
}
+реиндексация, спасибо всем!
__________________
..в каждой программе есть хотя бы одна ошибка..
Теги
ax3.0, ledgerjournaltrans, sql 2000, производительность

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Проблема при рестарте AOS DenisS DAX: Администрирование 4 20.07.2009 17:33
Проблема с единицей измерения longson DAX: Программирование 4 16.07.2007 14:35
Проблема с созданием объекта Lelya DAX: Администрирование 33 27.06.2005 16:38
Проблема: русские шрифты в отчетах, формируемых на сервере. Anais DAX: Администрирование 3 17.11.2003 13:20
ПРОБЛЕМА С ФИЛЬТРАЦИЕЙ В ФОРМЕ!!! VES DAX: Программирование 9 25.04.2003 15:28

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 06:53.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.