Не удается получить внешнее объединение или присоединение notexists для работы в AX 2009
У меня есть полностью пустая пользовательская таблица (DatabaseLogFixLog) только с одним полем / столбцом с именем "refRecId". Я присоединяюсь к SysDatabaseLog (log). План состоит в том, чтобы обновлять SysDatabaseLog партиями, и когда я обновляю SysDatabaseLog, я вставлю recId строки, которую я обновил. Мой SysDatabaseLog содержит 3,7 миллиона записей. Я попробовал оба соединения notexists и внешнего соединения, показанные ниже. Что не так с моим кодом? Оба просто полностью блокируют мою систему, и отладчик не попадет внутрь циклов.
Внешнее соединение:
updateCounter = 10;
while select forupdate log
order by CreatedDateTime, RecId
outer join databaseLogFixLog
where databaseLogFixLog.RefRecId != log.RecId
{
counter++;
if (counter > updateCount)
break;
info(strfmt("%1", counter));
}
info(strfmt("Done updating %1", counter));
Записки присоединяются:
updateCounter = 10;
while select forupdate log
order by CreatedDateTime, RecId
notexists join databaseLogFixLog
where databaseLogFixLog.RefRecId == log.RecId
{
counter++;
if (counter > updateCount)
break;
info(strfmt("%1", counter));
}
info(strfmt("Done updating %1", counter));
2 ответа
Ваши два соединения не эквивалентны, ваше внешнее соединение просто неправильно.
Вы существуете, объединение будет работать, но оно должно будет отсортировать записи вашего журнала (3,7 миллиона), ведь это займет некоторое время. Также он должен проверить, есть ли у вас logFixLog
запись существует (для каждого из 3,7 миллионов), вам понадобится индекс на RefRecId
поле, чтобы ускорить вещи.
Если вы хотите скорость, то удалите order by
пункт.
Вы также можете попробовать добавить firstfast
Ключевое слово, иногда оно дает более быстрые начальные результаты (но редко в сочетании с order by
).
Наконец, выберите поля, которые вы хотите обновить, особенно избегайте поля контейнера, так как это поле не сохраняется вместе с другими полями.
Я не думаю, что я бы зациклился на таком огромном наборе данных с ключевым словом "forupdate", а скорее использовал бы один буфер таблиц для зацикливания (log) и другой для обновления (logUpdate).
Я могу себе представить, что система зависает, когда она перебирает 3,7 миллиона записей, и пока выполняется запрос, вам придется подождать, пока он, наконец, не войдет внутрь while-select.
Также убедитесь, что у RefRecId есть индекс для таблицы, чтобы ядро базы данных не запускало полное сканирование таблицы, пытаясь найти строку в databaseLogFixLog.