Показать сообщение отдельно
Старый 24.01.2018, 13:10   #50  
БАХ43 is offline
БАХ43
Участник
 
92 / 54 (2) ++++
Регистрация: 15.02.2013
Адрес: г.Москва, г. Зеленоград
Тоже недавно понадобилось почистить неиспользуемые 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++ ???

Последний раз редактировалось БАХ43; 24.01.2018 в 13:15.