При регрессионном тестировании, проверке корректности обменов или после масштабных обновлений часто возникает задача сверки огромных массивов данных (например, регистров бухгалтерии или накопления) между двумя базами. Если счет идет на сотни мегабайт или гигабайты, классический запрос падает из-за нехватки оперативной памяти, а перебор таблиц в цикле занимает непозволительно много времени. Проанализируем ситуацию и разберем по шагам наиболее эффективные подходы для быстрого сравнения больших таблиц.
Самым производительным решением для баз размером в сотни гигабайт является сравнение данных, минуя сервер 1С. СУБД изначально оптимизированы для подобных задач. Рассмотрим подробнее, как это можно реализовать:
ВнешниеИсточникиДанных. Это позволяет писать запросы внутри 1С, обращаясь к удаленной таблице почти как к локальной.postgres_fdw (для PostgreSQL).При использовании прямого SQL-запроса через связанные серверы, разницу можно получить мгновенно, применяя операторы EXCEPT или FULL OUTER JOIN.
Когда таблицы действительно гигантские и физически разнесены (например, базы находятся в разных городах), передавать все данные по сети нецелесообразно. В таких случаях спасает хэширование.
Посмотрим на пример алгоритма:
Если прямого соединения между базами нет, и необходимо использовать файлы выгрузки, классический подход с выгрузкой отчета в MXL не подойдет из-за исчерпания памяти. Разберем решение с потоковым чтением.
Алгоритм потокового сравнения:
ЧтениеXML или ЧтениеJSON.Существуют специализированные алгоритмы, позволяющие минимизировать извлечение ссылочных данных. Выясним причину их эффективности: нет смысла сразу тянуть все ссылки (выполнять ЗначениеИзСтрокиВнутр) для огромного массива, если расхождения есть только в паре сотен строк.
Суть метода половинного поиска заключается в следующем: мы сравниваем контрольные суммы (или итоги) отрезков данных. Весь массив делится пополам. Если контрольные суммы первой половины в обеих базах совпадают, мы эту половину отбрасываем. Если нет — делим ее снова пополам. Этот алгоритм позволяет найти все расхождения за логарифмическое время.
Если объемы позволяют загрузить порцию данных во временную таблицу (ВТ), мы можем доверить слияние серверу 1С. Рассмотрим этот подход:
ПОЛНОЕ СОЕДИНЕНИЕ к целевой таблице регистра или справочника.ГДЕ ставим условие на неравенство ресурсов или ЕСТЬ NULL у ключей соединяемых таблиц.
ВЫБРАТЬ
ЕСТЬNULL(ВнешняяВТ.Ключ, ЛокальнаяТБ.Ключ) КАК Ключ,
ВнешняяВТ.Сумма КАК СуммаВнешняя,
ЛокальнаяТБ.Сумма КАК СуммаЛокальная
ИЗ
ВнешняяТаблица КАК ВнешняяВТ
ПОЛНОЕ СОЕДИНЕНИЕ ТаблицаБазы КАК ЛокальнаяТБ
ПО ВнешняяВТ.Ключ = ЛокальнаяТБ.Ключ
ГДЕ
(ВнешняяВТ.Ключ ЕСТЬ NULL
ИЛИ ЛокальнаяТБ.Ключ ЕСТЬ NULL
ИЛИ ВнешняяВТ.Сумма <> ЛокальнаяТБ.Сумма)
Если задача заключается в регулярном регрессионном тестировании, логичнее не сверять все данные заново каждый раз. Разберем по шагам оптимизацию этого процесса:
ПланыОбмена для фиксации изменений тех объектов, которые затрагивает тест.Не забывайте про встроенные инструменты платформы и библиотек. Например, Схема Компоновки Данных (СКД) отлично справляется со слиянием двух внешних наборов данных в оперативной памяти. Вы можете передать две таблицы значений в СКД, связать их и вывести только различающиеся строки.
Также, если данные уже загружены в память в виде коллекций, можно использовать функцию Библиотеки Стандартных Подсистем ОбщегоНазначения.КоллекцииИдентичны(). Она автоматически проверит структуру и содержимое, избавив вас от написания рутинных циклов перебора.