Тоже недавно понадобилось почистить неиспользуемые InventDim. Использовал класс InventUnusedDimCleanUp. Все прекрасно, за час-два осталось 7 млн записей из 16 млн. НО!!! После этого залез в таблицу и невооруженным глазом заметил несколько явно неиспользуемых аналитик. В методе deleteUsedIdsFromCleanUpTable поставил заплаточку:
X++:
while( listEnumerator.moveNext() )
{
// ->
select firstonly inventDimCleanUp
where inventDimCleanUp.InventDimId == "УЗАН000434";
if (!inventDimCleanUp && tableId)
{
warning(strfmt("Аналитика = %1 найдена в таблице %2 (%3) (%4)", inventDimCleanUp.InventDimId, tableid2pname(tableId), tableid2name(tableId), fieldId2name(tableId, fieldId)));
}
// <-
tableAndField = listEnumerator.current();
tableId = conpeek(tableAndField, 1);
fieldId = conpeek(tableAndField, 2);
по которой определил, что искомая аналитика удаляется при анализе таблицы WMSOrder. В этой таблице такой аналитики не оказалось ни в InventDimId, ни в toInventDimId. Задумался о легитимности метода deleteInventDimCleanUp.
Поставил еще одну заплаточку:
X++:
tableAndField = listEnumerator.current();
tableId = conpeek(tableAndField, 1);
fieldId = conpeek(tableAndField, 2);
// ->
dictTable = new DictTable(tableId);
common = dictTable.makeRecord();
info(strfmt("%1 (%2) Id = %3", tableid2pname(tableId), tableid2name(tableId), tableId));
select count(RecId) from inventDimCleanUp
exists join common
where inventDimCleanUp.InventDimId == common.(fieldId);
warning(strfmt("Найдено %1 записей", inventDimCleanUp.RecId));
select count(RecId) from inventDimCleanUp;
recToDel = inventDimCleanUp.RecId;
// <-
// Update progress bar
progress.incCount();
progress.setText( tableid2pname(tableId) );
// The InventDim is being used, remove it from the list of unused InventDims
this.deleteInventDimCleanUp(connection, tableId, fieldId);
deleted ++;
//->
select count(RecId) from inventDimCleanUp;
recToDel -= inventDimCleanUp.RecId;
warning(strfmt("Удалено %1 записей", recToDel));
// <-
В итоге получил такой инфолог:
Код:
Складской заказ (WMSOrder) Id = 666
Найдено 37141 записей
Удалено 102098 записей
Складской заказ (WMSOrder) Id = 666
Найдено 23159 записей
Удалено 23161 записей
Проводки заказа запасов (WMSOrderTrans) Id = 716
Найдено 9 записей
Удалено 9 записей
Проводки заказа запасов (WMSOrderTrans) Id = 716
Найдено 856640 записей
Удалено 858638 записей
То есть оказалось, что запрос в X++
X++:
select count(RecId) from inventDimCleanUp
exists join common
where inventDimCleanUp.InventDimId == common.(fieldId);
и запрос, формируемый для SQL в методе deleteInventDimCleanUp
Код:
DELETE FROM INVENTDIMCLEANUP WHERE EXISTS (SELECT 'x' FROM WMSORDER T WHERE (INVENTDIMCLEANUP.INVENTDIMID = T.INVENTDIMID))
обрабатывают разное количество записей.
Кто подскажет, в чем может быть дело. Или плюнуть на высокую производительность запроса SQL и удалять записи через delete_from из X++ ???