Показать сообщение отдельно
Старый 29.11.2011, 11:26   #11  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,867 / 3123 (112) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Поковырял еще тему с оптимизацией
см. еще
axdaily: SQL temporary tables in AX 2012

Оказалось, что нелинейность прячется не в классе Tax а при прописывании налогов в строки документа.

Например для класса PurchFormLetter_Invoice в методе writeTaxAmount_W
есть код
X++:
invoiceTrans.initFromTaxWorkTrans_RU(this.tmpTaxWorkTrans(vendInvoiceJour.RecId),
                                              tablenum(PurchLine),
                                              0,
                                              invoiceTrans.InventTransId);
А метод tmpTaxWorkTrans зачем то дублирует временную табличку.
Получается что мы перебираем N строк накладной и на каждой строке копируем времянку через while select { buffer.insert() } т.е. тоже выполняем N шагов. Итого сложность алгоритма N^2 - квадратичная.

Исправить можно например так :

X++:
protected void writeTaxAmount_W()
{
    VendInvoiceTrans invoiceTrans;
    CRSEFeatures_W   features = CompanyInfo::features_W();
    TmpTaxWorkTrans     GRD_locTmpTaxWorkTrans; //+GRD_R4719_SpeedUpFormLetter_pkoz, pkoz, 24.11.2011

    if (features != CRSEFeatures_W::PL &&
        features != CRSEFeatures_W::RU)
        return;

    if (! TaxParameters::find().TaxSpecifyLine)
        return;

    // GRD_R4719_SpeedUpFormLetter_pkoz, pkoz, 24.11.2011 -->
     GRD_locTmpTaxWorkTrans = this.tmpTaxWorkTrans(vendInvoiceJour.RecId);
    // GRD_R4719_SpeedUpFormLetter_pkoz, pkoz, 24.11.2011 <--

    while select forupdate invoiceTrans
        index hint InvoiceIdx
        where invoiceTrans.PurchID             == vendInvoiceJour.PurchId           &&
              invoiceTrans.InvoiceId           == vendInvoiceJour.InvoiceId         &&
              invoiceTrans.InvoiceDate         == vendInvoiceJour.InvoiceDate       &&
              invoiceTrans.InternalInvoiceId   == vendInvoiceJour.InternalInvoiceId &&
              invoiceTrans.NumberSequenceGroup == vendInvoiceJour.NumberSequenceGroup
    {        
        invoiceTrans.initFromTaxWorkTrans_RU(
// GRD_R4719_SpeedUpFormLetter_pkoz, pkoz, 24.11.2011 -->
                                             //this.tmpTaxWorkTrans(vendInvoiceJour.RecId),
                                             GRD_locTmpTaxWorkTrans,
// GRD_R4719_SpeedUpFormLetter_pkoz, pkoz, 24.11.2011 <--
                                             tablenum(PurchLine),
                                             0,
                                             invoiceTrans.InventTransId);
        invoiceTrans.doUpdate();
    }
}
Для других классов семейства FormLetter исправляется аналогично.
На документах из 1000 строк экономия времени составила примерно 10 минут. Для документов из 100 строк не замерял, но думаю что немного.

Интересно что эта ошибка тянется еще с Ax 3.0
За это сообщение автора поблагодарили: lev (5), gl00mie (10), someOne (6).