|  06.11.2008, 18:30 | #1 | 
| Модератор |  Оптимизация кода с LedgerTrans 
			
			Есть в Axapte 3 SP6 class LedgerRRGOperationBalanceTotal_RU метод  X++: public AmountMST calc() { AmountMST sumTmp, balanceAmountMST; balanceAmountMST = 0; if (m_PEriodType == LedgerRRGBalancePeriodType_RU::Incoming) m_CalculateDate -= 1; while select m_AccountList outer join m_LedgerTrans where m_LedgerTrans.TransDate <= m_CalculateDate && m_AccountList.AccountNum == m_LedgerTrans.AccountNum && m_LedgerTrans.PeriodCode == PeriodCode::Regular { if (this.checkTransaction(m_LedgerTrans.TransType, m_LedgerTrans.OperationsTax, m_LedgerTrans.Correct, m_LedgerTrans.Dimension, '')) { if (m_currencyForCalc == LedgerRRGCurrencyForCalc_RU::AmountMST) { sumTmp = m_LedgerTrans.AmountMST; } else { sumTmp = m_LedgerTrans.AmountMSTSecond; } balanceAmountMST += (m_AccountList.ReverseSign ? (-1) : 1) * sumTmp; } } return balanceAmountMST; } | 
|  | 
|  06.11.2008, 19:05 | #2 | 
| Участник | Цитата: Во-вторых, прекратить извращение с суммированием от начала времен и использовать промежуточные итоги из LedgerBalancesDimTrans. | 
|  | 
|  06.11.2008, 19:10 | #3 | 
| NavAx | 
			
			В-третьих, использовать sum() и group by. В-четвертых, перенести генератор из DAX 4. | 
|  | |
| За это сообщение автора поблагодарили: gl00mie (2). | |
|  06.11.2008, 19:20 | #4 | 
| Модератор | 
			
			mazzy по вашему outer joint тут вообще не нужен?  raz Цитата: 
		
			В-четвертых, перенести генератор из DAX 4.
		
	 | 
|  | 
|  06.11.2008, 19:25 | #5 | 
| Модератор | 
			
			На сколько необходим вызов табличного метода postLoad() при каждом обращении к LedgerTrans ? Деактивировать его можно или не нужно? | 
|  | 
|  06.11.2008, 19:49 | #6 | 
| NavAx | X++: public AmountMST calc() { AmountMST sumTmp, balanceAmountMST; balanceAmountMST = 0; if (m_PEriodType == LedgerRRGBalancePeriodType_RU::Incoming) m_CalculateDate -= 1; while select m_AccountList while select sum(AmountMST), sum(AmountMSTSecond) from m_LedgerTrans group by TransType, OperationsTax, Correct, Dimension where m_LedgerTrans.TransDate <= m_CalculateDate && m_LedgerTrans.AccountNum == m_AccountList.AccountNum && m_LedgerTrans.PeriodCode == PeriodCode::Regular { if (this.checkTransaction(m_LedgerTrans.TransType, m_LedgerTrans.OperationsTax, m_LedgerTrans.Correct, m_LedgerTrans.Dimension, '')) { if (m_currencyForCalc == LedgerRRGCurrencyForCalc_RU::AmountMST) { sumTmp = m_LedgerTrans.AmountMST; } else { sumTmp = m_LedgerTrans.AmountMSTSecond; } balanceAmountMST += (m_AccountList.ReverseSign ? (-1) : 1) * sumTmp; } } return balanceAmountMST; } Цитата: 
		
			вы уверены, что можно его из 4 в 3 перенести?
		
	 | 
|  | |
| За это сообщение автора поблагодарили: Poleax (2). | |
|  06.11.2008, 20:15 | #7 | 
| Участник | |
|  | 
|  06.11.2008, 20:54 | #8 | 
| Участник | 
			
			Это конечно, да... Но снова суммирование идет от начала времен. Разберитесь как суммирует класс LedgerBalanceDim_CurrentMST и все семейство LedgerBalance* | 
|  | 
|  06.11.2008, 21:01 | #9 | 
| Member | Цитата: 
		
			Сообщение от raz
			
			 В-четвертых, перенести генератор из DAX 4. Там одно только сокращение выбираемых для каждой записи полей само по себе уже даст ощутимый прирост производительности. Но в 4.0 был реализован комплекс мер по повышению производительности. Глупо было бы не перенести. Тем более, что там функционал развивают. 
				__________________ С уважением, glibs® | 
|  | 
|  07.11.2008, 09:04 | #10 | 
| Участник | Цитата: Но гораздо больший прирост даст отсутствие перехваченного метода postload, а следовательно запрос будет целиком исполняться на SQL-сервере   | 
|  | 
|  07.11.2008, 09:16 | #11 | 
| Member | Цитата: 
		
			Сообщение от mazzy
			
			 ... запрос будет целиком исполняться на SQL-сервере ... 
				__________________ С уважением, glibs® | 
|  | 
|  07.11.2008, 09:31 | #12 | 
| Участник | 
			
			текстовая строка "Select <Бла-бла-бла> from <Бла-бла-бла> ...", которая выполняется НА СЕРВЕРЕ. поскольку у таблицы LedgerTrans переопределен метод postLoad, то умная Аксапта не посылает SQL-серверу запрос с просьбой посуммировать, а выбирает все записи по одной, применяет к каждой метод postLoad и суммирует сама. Поэтому для таблиц с перехваченным postLoad гораздо важнее сократить объем выборки, нежели делать агрегирование (raz, к великому сожалению для таблицы LeagerTrans ваш совет не очень помогает. Вот для других таблиц - да, очень полезный совет). Так вот. Русские отчеты написаны неправильно. Они не учитывают "особенность" таблицы LedgerTrans и суммируют "от начала времен". Что приводит к выборке в Аксапту каждой проводки из LedgerTrans, которая попадает в условие. Еще раз советую посмотреть как с этим вопросом справились в буржуйских финансовых отчетах. В буржуйских из LedgerTrans никогда не выбирается больше финансового периода - Большинство данных берется из промежуточных итогов. (надо также помнить, что финансовый период безболезненно можно разбить на несколько в случае чего) | 
|  | 
|  07.11.2008, 09:43 | #13 | 
| NavAx | Цитата: X++: static void Job1(Args _args) { ledgertrans lt; ; select sum(amountmst) from lt where lt.AccountNum == "zzz"; print(lt.AmountMST); pause; } Последний раз редактировалось raz; 07.11.2008 в 09:48. | 
|  | 
|  07.11.2008, 09:47 | #14 | 
| Member | 
			
			Я тоже не буду спорить   ... Но если поставить брякпоинт в методе .postLoad(), то с помощью дебагера и счетных палочек можно убедиться, что этот вражеский метод вызывается для результата GROUP BY, а не для каждого LedgerTrans в отдельности. 
				__________________ С уважением, glibs® | 
|  | |
| За это сообщение автора поблагодарили: mazzy (5). | |
|  07.11.2008, 09:51 | #15 | 
| NavAx | 
			
			Таким образом суммирование и группировка дают колоссальный эффект...
		 | 
|  | |
| За это сообщение автора поблагодарили: mazzy (10). | |
|  07.11.2008, 10:03 | #16 | 
| Member | 
			
			Вообще, тема относительно русских финотчетов уже была раскрыта... Генератор финансовых отчётов И даже обновление потом вышло. 
				__________________ С уважением, glibs® | 
|  | |
| За это сообщение автора поблагодарили: Poleax (2). | |
|  07.11.2008, 12:13 | #17 | 
| Модератор | 
			
			Какая интересная большая тема получилась.  Raz спасибо, твой код ускорил вывод отчета, с 3 часов до 12 минут. P.S. Данные в отчетах одинаковые  glibs Генератор финансовых отчётов Цитата: 
		
			2. Не то, чтобы радикально, но факт. Как это ни банально, но создание кластерных индексов на таблицах LedgerRRGAccountInterval_RU, LedgerRRGCellTable_RU, LedgerRRGDimensionInterval_RU, LedgerRRGOffsetAccountInterval_RU, LedgerRRGOperationTable_RU повышает скорость выборки данных для отчета. Еще раз повторю, что не радикально. Можно сказать даже не существенно на фоне вышеописанного. Ну и поставить EntireTable кэш на LedgerRRGReportTable_RU равно как и группу таблиц Group какой-нибудь вместо Misc тоже не помешает.
		
	 Последний раз редактировалось Poleax; 07.11.2008 в 12:25. | 
|  | 
|  07.11.2008, 12:14 | #18 | 
| Участник | 
			
			Все бы так "не спорили"   Я тут было хотел съехидничать по поводу упрощения задачи, про то, что в изначальном методе были офигительные Group by... Но просто проверил. ax3.0sp6, ax4.0sp2, ax2009. Результат одинаковый: Действительно группирует на сервере, невзирая на перекрытый метод PostLoad. Офигеть! X++: static void Job7(Args _args) { ledgertrans lt; ; while select sum(amountmst) from lt group by AccountNum, TransDate, PeriodCode, TransType, OperationsTax, Correct, Dimension where lt.AccountNum == "51.010" { print(lt.AmountMST); } } Интересно, когда поменяли? Ладно, спишем на мой старческий маразм. Спасибо вам огромное. Да. raz, ты прав! | 
|  | 
|  07.11.2008, 12:32 | #19 | 
| Участник | 
			
			Но тем не менее, это не повод заставлять SQL суммировать от начала времен   Выборку все равно нужно сокращать. | 
|  | 
| Теги | 
| ledgertrans, отчет, производительность, ax3.0, финансовые движения | 
|  | 
| 
 |