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, импорт данных, оптимизация, полезное, производительность |
|
|