|  14.05.2008, 15:40 | #1 | 
| ---------------- | Ускорение стандартного импорта 
			
			Промаявшись с импортом проводок по клиентам, решил в классе SysDataImport заменить пару временных таблиц на Map X++: class SysDataImport extends SysDataExpImp implements sysDeleteTables { ... // шустрый импорт --> // TmpTransactionIdMap old2NewCreatedTransactionId; // TmpTransactionIdMap old2NewModifiedTransactionId; Map old2NewCreatedTransactionId; Map old2NewModifiedTransactionId; // шустрый импорт <-- ... } X++: void new() { ... // шустрый импорт --> old2NewCreatedTransactionId = new Map(Types::Integer, Types::Integer); old2NewModifiedTransactionId = new Map(Types::Integer, Types::Integer); // шустрый импорт <-- } X++: private void updateTransactionId(TableId _tableId, CreatedTransactionId _oldCreatedTransId, ModifiedTransactionId _oldModifiedTransId) { CreatedTransactionId newTransId = 0; ; if (!hasTransIdSupport) { return; } if (hasCreatedTransId[tableIds[_tableId]]) { // шустрый импорт --> // select old2NewCreatedTransactionId where old2NewCreatedTransactionId.Id == _oldCreatedTransId; // if (old2NewCreatedTransactionId) // { // newTransId = old2NewCreatedTransactionId.RefId; // } if(old2NewCreatedTransactionId.exists(_oldCreatedTransId)) { newTransId = old2NewCreatedTransactionId.lookup(_oldCreatedTransId); } // шустрый импорт <-- if (newTransId) { curCommon.(new DictTable(curCommon.TableId).fieldName2Id(extendedtypestr(CreatedTransactionId))) = newTransId; } else { curCommon.(new DictTable(curCommon.TableId).fieldName2Id(extendedtypestr(CreatedTransactionId))) = nextTransId; // шустрый импорт --> // old2NewCreatedTransactionId.Id = _oldCreatedTransId; // old2NewCreatedTransactionId.RefId = nextTransId; // old2NewCreatedTransactionId.insert(); old2NewCreatedTransactionId.insert(_oldCreatedTransId, nextTransId); // шустрый импорт <-- nextTransId++; } } newTransId = 0; if (hasModifiedTransId[tableIds[_tableId]]) { // шустрый импорт --> // select old2NewModifiedTransactionId where old2NewModifiedTransactionId.Id == _oldModifiedTransId; // if (old2NewModifiedTransactionId) // { // newTransId = old2NewModifiedTransactionId.RefId; // } if(old2NewModifiedTransactionId.exists(_oldModifiedTransId)) { newTransId = old2NewModifiedTransactionId.lookup(_oldModifiedTransId); } // шустрый импорт <-- if (newTransId) { CurCommon.(new DictTable(curCommon.TableId).fieldName2Id(extendedtypestr(ModifiedTransactionId))) = newTransId; } else { curCommon.(new DictTable(curCommon.TableId).fieldName2Id(extendedtypestr(ModifiedTransactionId))) = nextTransId; // шустрый импорт --> // old2NewModifiedTransactionId.Id = _oldModifiedTransId; // old2NewModifiedTransactionId.RefId = nextTransId; // old2NewModifiedTransactionId.insert(); old2NewModifiedTransactionId.insert(_oldModifiedTransId, nextTransId); // шустрый импорт <-- nextTransId++; } } } X++: private void updateTransactionIdReference() { Counter fieldCount; Counter fieldCounter; FieldId fieldId; container fields; ; if (!hasTransIdSupport) { return; } fields = createdTransField[curCommon.TableId]; if (fields) { fieldCount = conlen(fields); for (fieldCounter=1;fieldCount<=fieldCounter;fieldCount++) { fieldId = conpeek(fields,fieldCount); if (isSysId(fieldId)) // If is a system field, it's already been handled through updateTransactionId { continue; } // шустрый импорт --> // select old2NewCreatedTransactionid where old2NewCreatedTransactionId.Id == curCommon.(fieldId); // if (old2NewCreatedTransactionId) // { // curCommon.(fieldId) = old2NewCreatedTransactionId.RefId; // } if (old2NewCreatedTransactionId.exists(curCommon.(fieldId))) { curCommon.(fieldId) = old2NewCreatedTransactionId.lookup(curCommon.(fieldId)); } // шустрый импорт <-- else { curCommon.(fieldId) = nextTransId; // шустрый импорт --> // old2NewCreatedTransactionId.Id = curCommon.(fieldId); // old2NewCreatedTransactionId.RefId = nextTransId; // old2NewCreatedTransactionId.insert(); old2NewCreatedTransactionId.insert(curCommon.(fieldId), nextTransId); // шустрый импорт <-- nextTransId++; } } } fields = modifiedTransField[curCommon.TableId]; if (fields) { fieldCount = conlen(fields); for (fieldCounter=1;fieldCount<=fieldCounter;fieldCount++) { fieldId = conpeek(fields,fieldCount); if (isSysId(fieldId)) // If is a system field, it's already been handled through updateTransactionId { continue; } // шустрый импорт --> // select old2NewModifiedTransactionid where old2NewModifiedTransactionid.Id == curCommon.(fieldId); // if (old2NewModifiedTransactionid) // { // curCommon.(fieldId) = old2NewModifiedTransactionid.RefId; // } if (old2NewModifiedTransactionid.exists(curCommon.(fieldId))) { curCommon.(fieldId) = old2NewModifiedTransactionid.lookup(curCommon.(fieldId)); } // шустрый импорт <-- else { curCommon.(fieldId) = nextTransId; // шустрый импорт --> // old2NewModifiedTransactionid.Id = curCommon.(fieldId); // old2NewModifiedTransactionid.RefId = nextTransId; // old2NewModifiedTransactionid.insert(); old2NewModifiedTransactionid.insert(curCommon.(fieldId), nextTransId); // шустрый импорт <-- nextTransId++; } } } } Импорт занял 2889 секунд для 1801345 записей. Таблицы: CustTrans, VendTrans, LedgerTrans, CustTransOpen, CustSettlement и т.д. | 
|  | |
| За это сообщение автора поблагодарили: Vadik (1), gl00mie (5). | |
|  14.05.2008, 16:54 | #2 | 
| очами вижу | 
			
			Я, конечно, понимаю, что такое комментирование - это так называемые "Best Practices", но не кажется ли вам, что они лишь мешают чтению кода? Не лучше ли, чтобы история изменений хранилась в системе контроля версий, а в коде был код и комментарии к нему? | 
|  | 
|  14.05.2008, 19:03 | #3 | 
| Участник | Цитата: Можно поподробнее как и чем нужно было закоментировать или вообще не нужно. | 
|  | 
|  14.05.2008, 22:40 | #4 | 
| Участник | |
|  | 
|  15.05.2008, 10:51 | #5 | 
| ---------------- | 
			
			Пару лет   За сутки даже не доделал CustTrans, так как очень скоро временные таблицы вылезали на диск и при каждом обращении к ним делалось чтение построчно (по 48 байт). Интервалы между вставками записей в SQL-таблицу становятся больше 1 секунды уже через несколько минут непрерывного импорта. | 
|  | 
|  15.05.2008, 11:24 | #6 | 
| Участник | 
			
			А можно этот код проектом выложить? Имхо это можно в базу знаний.
		 | 
|  | 
|  15.05.2008, 11:43 | #7 | 
| ---------------- | 
			
			Я не могу, так как на всех приложениях, которые у меня есть, этот класс различается в classDeclaration и new. А делать проектики под разные версии лениво. Думаю, кому захочется попробовать смогут и отсюда скопировать и все вставить куда надо.
		 | 
|  | 
|  17.05.2008, 10:37 | #8 | 
| Участник | Небольшой штрих Цитата: 
		
			Сообщение от Wamr
			   Промаявшись с импортом проводок по клиентам, решил в классе SysDataImport заменить пару временных таблиц на Map ... X++: void new() { ... // шустрый импорт --> old2NewCreatedTransactionId = new Map(Types::Integer, Types::Integer); old2NewModifiedTransactionId = new Map(Types::Integer, Types::Integer); // шустрый импорт <-- } typeId2Type( typeid( CreatedTransactionId ) ) == Types::Int64 typeId2Type( typeid( ModifiedTransactionId ) ) == Types::Int64 Для совместимости кода Axapta 3.0 и DAX 4.0 небольшая поправка в инициализации Map'ов : X++: void new() { ... // шустрый импорт --> old2NewCreatedTransactionId = new Map( typeId2Type( typeid( CreatedTransactionId ), typeId2Type( typeid( CreatedTransactionId ) ) ); old2NewModifiedTransactionId = new Map( typeId2Type( typeid( ModifiedTransactionId ) ), typeId2Type( typeid( ModifiedTransactionId ) ) ); // шустрый импорт <-- } | 
|  | |
| За это сообщение автора поблагодарили: Wamr (3). | |
| Теги | 
| faq, импорт данных, оптимизация, полезное, производительность | 
|  | 
| 
 |