последние трое суток провёл в занимательном чтении топиков с названиями вида "оптимизация запроса", но так и не нашёл ответа на свой вопрос. точнее, на несколько. озвучу их, плавно переходя от частного к общему. (дело происходит в 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);
}
}
}
}
большое спасибо!