|
![]() |
#1 |
Роман Долгополов (RDOL)
|
Как обращаться к такой таблице в коде? Первый вариант уже сказали - табличный мап и инициализация через MakeRecord. Второй вариант - дублировать таблицу чтобы FieildId были такие как в таблице с решетом и то-же инициализация через MakeRecord. В этом случае заработают insert-update-delete_recordset. Этакий хакерский мап в виде таблицы.
Работа с мапом обычным (mInventSumDeltaKeyMap - мап) X++: mInventSumDeltaKeyMap inventSumDeltaKey = mInventSumDeltaKeyMap::tmpTableInit(); InventSum inventSum; InventSum inventSumNew; RecordInsertList insertList; ; while select ItemId, InventDimId from inventSumDeltaKey group by ItemId, InventDimId notexists join inventSum where inventSum.ItemId == inventSumDeltaKey.ItemId && inventSum.InventDimId == inventSumDeltaKey.InventDimId { if (!inventSumDeltaKey.ItemId || !inventSumDeltaKey.InventDimId) { throw error(strfmt("@SYS68912",funcname())); } if (! insertList) { insertList = new RecordInsertList(tablenum(InventSum), true, true, true); } inventSumNew.ItemId = inventSumDeltaKey.ItemId; inventSumNew.InventDimId = inventSumDeltaKey.InventDimId; inventSumNew.ClosedQty = NoYes::Yes; inventSumNew.Closed = NoYes::Yes; insertList.add(inventSumNew); } if (insertList) { insertList.insertDatabase(); } X++: mLedgerBalancesTransDeltaMap ledgerBalancesTransDelta = trecord::init(this.getBalanceDeltaTableId()); ; unchecked(Uncheck::TableSecurityPermission) { insert_recordset ledgerBalancesTrans (AccountNum, PeriodCode, TransDate, SystemGeneratedUltimo, DebitMST, CreditMST, DebitOPRMST, CreditOPRMST, DebitTaxMST, CreditTaxMST, DebitMSTSecond, CreditMSTSecond, DebitOPRMSTSecond, CreditOPRMSTSecond, DebitTaxMSTSecond, CreditTaxMSTSecond, Qty) select forceLiterals LedgerAccountNum, PeriodCode, TransDate, SystemGeneratedUltimo, sum(DebitMST), sum(CreditMST), sum(DebitOPRMST), sum(CreditOPRMST), sum(DebitTaxMST), sum(CreditTaxMST), sum(DebitMSTSecond), sum(CreditMSTSecond), sum(DebitOPRMSTSecond), sum(CreditOPRMSTSecond), sum(DebitTaxMSTSecond), sum(CreditTaxMSTSecond), sum(Quantity) from ledgerBalancesTransDelta group by LedgerAccountNum, PeriodCode, TransDate, SystemGeneratedUltimo; } X++: mInventSumDateTransTmp transTmp = trecord::init(_tableId, false, true); mInventSumDateDim dim; mInventSumDateTrans trans; #mInventSumDateDimDevelop insert_recordset transTmp (TransDate, ItemId, FinancialDimId) select maxof(TransDate), ItemId, FinancialDimId from trans group by ItemId, FinancialDimId where trans.TransDate <= transDate && (!inventSumDateDimParmCriteria.ItemIdFlag || (trans.ItemId == inventSumDateDimCriteria.ItemId)) join dim where dim.FinancialDimId == trans.FinancialDimId && (!inventSumDateDimParmCriteria.InventSiteIdFlag || (dim.InventSiteId == inventSumDateDimCriteria.InventSiteId )) && (!inventSumDateDimParmCriteria.InventLocationIdFlag || (dim.InventLocationId == inventSumDateDimCriteria.InventLocationId )) && (!inventSumDateDimParmCriteria.InventProfileIdFlag || (dim.InventProfileId == inventSumDateDimCriteria.InventProfileId )) && (!inventSumDateDimParmCriteria.InventProfileItemTypeFlag || (dim.InventProfileItemType == inventSumDateDimCriteria.InventProfileItemType)) && (!inventSumDateDimParmCriteria.AccountFlag || (dim.Account == inventSumDateDimCriteria.Account )) && (!inventSumDateDimParmCriteria.Account2Flag || (dim.Account2 == inventSumDateDimCriteria.Account2 )) && (!inventSumDateDimParmCriteria.AccountOffsetFlag || (dim.AccountOffset == inventSumDateDimCriteria.AccountOffset )) && (!inventSumDateDimParmCriteria.AccountOffset2Flag || (dim.AccountOffset2 == inventSumDateDimCriteria.AccountOffset2 )) && (!inventSumDateDimParmCriteria.StornoFlag || (dim.Storno == inventSumDateDimCriteria.Storno )) && (!inventSumDateDimParmCriteria.DimensionFlag[1] || (dim.Dimension[1] == inventSumDateDimCriteria.Dimension[1] )) && (!inventSumDateDimParmCriteria.DimensionFlag[2] || (dim.Dimension[2] == inventSumDateDimCriteria.Dimension[2] )) && (!inventSumDateDimParmCriteria.DimensionFlag[3] || (dim.Dimension[3] == inventSumDateDimCriteria.Dimension[3] )) && (!inventSumDateDimParmCriteria.DimensionFlag[4] || (dim.Dimension[4] == inventSumDateDimCriteria.Dimension[4] )) && (!inventSumDateDimParmCriteria.DimensionFlag[5] || (dim.Dimension[5] == inventSumDateDimCriteria.Dimension[5] )) && (!inventSumDateDimParmCriteria.DimensionFlag[6] || (dim.Dimension[6] == inventSumDateDimCriteria.Dimension[6] )) && (!inventSumDateDimParmCriteria.DimensionFlag[7] || (dim.Dimension[7] == inventSumDateDimCriteria.Dimension[7] )) && (!inventSumDateDimParmCriteria.DimensionFlag[8] || (dim.Dimension[8] == inventSumDateDimCriteria.Dimension[8] )) && (!inventSumDateDimParmCriteria.DimensionFlag[9] || (dim.Dimension[9] == inventSumDateDimCriteria.Dimension[9] )) && (!inventSumDateDimParmCriteria.DimensionFlag[10] || (dim.Dimension[10] == inventSumDateDimCriteria.Dimension[10] )) && (!inventSumDateDimParmCriteria.DimensionFlag[11] || (dim.Dimension[11] == inventSumDateDimCriteria.Dimension[11] )) && (!inventSumDateDimParmCriteria.DimensionFlag[12] || (dim.Dimension[12] == inventSumDateDimCriteria.Dimension[12] )) && (!inventSumDateDimParmCriteria.DimensionFlag[13] || (dim.Dimension[13] == inventSumDateDimCriteria.Dimension[13] )) && (!inventSumDateDimParmCriteria.DimensionFlag[14] || (dim.Dimension[14] == inventSumDateDimCriteria.Dimension[14] )) && (!inventSumDateDimParmCriteria.DimensionFlag[15] || (dim.Dimension[15] == inventSumDateDimCriteria.Dimension[15] )) && (!inventSumDateDimParmCriteria.DimensionFlag[16] || (dim.Dimension[16] == inventSumDateDimCriteria.Dimension[16] )) && (!inventSumDateDimParmCriteria.DimensionFlag[17] || (dim.Dimension[17] == inventSumDateDimCriteria.Dimension[17] )) && (!inventSumDateDimParmCriteria.DimensionFlag[18] || (dim.Dimension[18] == inventSumDateDimCriteria.Dimension[18] )); } |
|
|
За это сообщение автора поблагодарили: raz (20), Logger (20), Ace of Database (19). |
![]() |
#2 |
Moderator
|
Цитата:
Сообщение от db
![]() Не в коня корм от задачи зависит как обычно. В моем случае темповыми стали InventSumDelta и LedgerBalancesTransDelta. Результат - ПОЛНОЕ отсутствие блокировок при обновлении запасов в наличии и балансов по ГК. Полное означает не облегчение, а устранение проблемы на корню и возможность многопоточной разноски документов в тысячи реально параллельных не ждущих друг друга потоков. И такие странные методы стоили достигнутого результата
|
|
|
За это сообщение автора поблагодарили: Logger (3). |
![]() |
#3 |
Участник
|
|
|
![]() |
#4 |
Moderator
|
Цитата:
А когда мы индекс по RecId удаляем, системе не остается ничего другого кроме как использовать единственный кластерный индекс. А при этом блокировки случаются эдак на 2-3 порядка реже чем при использовании индекса по RecId. Ну то есть - решение Романа, вероятно, еще более универсально, поскольку вероятность блокировок доводит до нуля, но отрубить индекс по RecId не долго, а результат дает почти такой же, как и использование временной таблицы.... Последний раз редактировалось fed; 20.01.2019 в 14:24. |
|
|
За это сообщение автора поблагодарили: Logger (3), Raven Melancholic (5). |
![]() |
#5 |
Участник
|
Насколько понимаю, такое поведение из-за того, что в этой таблице постоянные добавления/удаления и она небольшая и поэтому сложно поддерживать правильную статистику чтобы SQL мог определить нормальный план запроса даже если за базой "следят".
Получается, что в таблицах, в которых очень часто меняются данные, влияющие на индексы, и записей немного, нужно свести индексы к тому, чтобы остались только те, что нужны для конкретных поисков. Не исключено, что в конкретном месте нужна подсказка какой индекс использовать, иначе получается ошибка оптимизации? |
|
![]() |
#6 |
Moderator
|
Цитата:
Сообщение от Raven Melancholic
![]() Насколько понимаю, такое поведение из-за того, что в этой таблице постоянные добавления/удаления и она небольшая и поэтому сложно поддерживать правильную статистику чтобы SQL мог определить нормальный план запроса даже если за базой "следят".
Получается, что в таблицах, в которых очень часто меняются данные, влияющие на индексы, и записей немного, нужно свести индексы к тому, чтобы остались только те, что нужны для конкретных поисков. Не исключено, что в конкретном месте нужна подсказка какой индекс использовать, иначе получается ошибка оптимизации? |
|
![]() |
#7 |
Участник
|
Цитата:
С другой стороны, размер места для таблицы несколько десятков мегабайт, то есть еженочная оптимизация и перестройка индексов не затронула кластерный индекс этой таблицы (при его перестройке место освобождается). Стоит задуматься над тем, что там у нас ночью происходит или над тем, что в течение дня было, что так увеличился размер, если ночью он был высвобожден. Не исключено, что именно перевод в TempDB поможет. |
|
![]() |
#8 |
Участник
|
Цитата:
Сообщение от db
![]() Не в коня корм от задачи зависит как обычно. В моем случае темповыми стали InventSumDelta и LedgerBalancesTransDelta. Результат - ПОЛНОЕ отсутствие блокировок при обновлении запасов в наличии и балансов по ГК. Полное означает не облегчение, а устранение проблемы на корню и возможность многопоточной разноски документов в тысячи реально параллельных не ждущих друг друга потоков. И такие странные методы стоили достигнутого результата
![]()
__________________
Мои утилиты для Аксапты версий 3.0-2012: http://aceofdatabase.blogspot.com/ Последний раз редактировалось Ace of Database; 20.01.2019 в 18:03. |
|
![]() |
#9 |
Участник
|
Цитата:
Если перевести InventSumDelta в TempDB, то обращение в отдельном классе будет обращаться к той же темповой таблице, что и в другом месте или нужны какие-то дополнительные действия? В DAX2012, чтобы в разных местах были обращения к одной и той же темповой таблице из TempDB приходится немного помашанить иначе разные курсоры создают разные #что-то_в_TempDB. |
|
![]() |
#10 |
Участник
|
Цитата:
Код: mInventSumDeltaKeyMap::tmpTableInit(); Код: trecord::init(this.getBalanceDeltaTableId()); То есть, существует ли вариант получения TableId таблицы таким образом, чтобы сохранялись перекрестные ссылки, чтобы про изменения например наименования сообщал компилятор при компиляции перед релизом, а не разъяренный пользователь после релиза. А мне интересен технический момент: если я в InventUpd_* буду использовать эти временные InventSumDelta, то смогу ли обратиться именно к этому конкретному экземпляру временной таблицы в InventOnHand? Ясно, что если этот подход помогает, то с чем-то можно смириться. |
|
![]() |
#11 |
Роман Долгополов (RDOL)
|
Цитата:
|
|
![]() |
#12 |
Участник
|
Цитата:
X++: InventUpdateOnhandGlobal::mustAddInventSumDeltaOnhand(itemId) |
|
Теги |
dispose, inventsumdelta, ledgerbalancestransdelta, tempdb |
|
|