Как быстро сравнить большие таблицы между двумя базами 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При регрессионном тестировании, проверке корректности обменов или после масштабных обновлений часто возникает задача сверки огромных массивов данных (например, регистров бухгалтерии или накопления) между двумя базами. Если счет идет на сотни мегабайт или гигабайты, классический запрос падает из-за нехватки оперативной памяти, а перебор таблиц в цикле занимает непозволительно много времени. Проанализируем ситуацию и разберем по шагам наиболее эффективные подходы для быстрого сравнения больших таблиц.

Сравнение на уровне СУБД и внешние источники данных

Самым производительным решением для баз размером в сотни гигабайт является сравнение данных, минуя сервер 1С. СУБД изначально оптимизированы для подобных задач. Рассмотрим подробнее, как это можно реализовать:

  1. Внешние источники данных (ВИД): Если между базами есть сетевое соединение, удобнее всего подключить таблицы одной базы к другой через механизм ВнешниеИсточникиДанных. Это позволяет писать запросы внутри 1С, обращаясь к удаленной таблице почти как к локальной.
  2. Связанные серверы СУБД: Если базы лежат на одном SQL-сервере или в одной сети, мы можем использовать технологию Linked Servers (для MS SQL) или расширения вроде postgres_fdw (для PostgreSQL).
  3. Экспорт в промежуточную SQL-базу: Можно выгрузить нужные поля в легковесную базу вроде SQLite или отдельную базу MS SQL. Скорость чтения 1С достаточно высока, а затем средствами чистого SQL выполняется поиск расхождений.

При использовании прямого SQL-запроса через связанные серверы, разницу можно получить мгновенно, применяя операторы EXCEPT или FULL OUTER JOIN.

Использование хэширования записей

Когда таблицы действительно гигантские и физически разнесены (например, базы находятся в разных городах), передавать все данные по сети нецелесообразно. В таких случаях спасает хэширование.

Посмотрим на пример алгоритма:

  1. В первой базе для каждой строки формируется хэш по всем значимым ресурсам и измерениям (или текстовому представлению строки).
  2. Во второй базе выполняется аналогичная операция.
  3. Для сравнения передаются не сами данные, а только компактная связка "УИД + Хэш". Объем передаваемых данных снижается до 5% от исходного.
  4. Сравниваются только хэши. Если хэши по ключу не совпадают (или ключ отсутствует), мы фиксируем расхождение и уже адресно запрашиваем полные данные по этой строке для анализа.

Потоковое чтение и скользящее окно (XML/JSON)

Если прямого соединения между базами нет, и необходимо использовать файлы выгрузки, классический подход с выгрузкой отчета в MXL не подойдет из-за исчерпания памяти. Разберем решение с потоковым чтением.

Алгоритм потокового сравнения:

  1. Данные из первой базы выгружаются в оптимизированный XML или JSON файл. Каждая порция данных (например, 1000 строк) оборачивается в элемент верхнего уровня.
  2. Во второй базе файл читается не целиком в память, а последовательно, через объект ЧтениеXML или ЧтениеJSON.
  3. Применяется метод "скользящего окна": считанная из файла порция сравнивается с аналогичной выборкой из БД второй базы.
  4. Позиция отслеживается по номеру считанного элемента. Если процесс прерывается, регламентное задание может восстановить чтение с последней точки.

Алгоритм половинного поиска (Бинарное деление)

Существуют специализированные алгоритмы, позволяющие минимизировать извлечение ссылочных данных. Выясним причину их эффективности: нет смысла сразу тянуть все ссылки (выполнять ЗначениеИзСтрокиВнутр) для огромного массива, если расхождения есть только в паре сотен строк.

Суть метода половинного поиска заключается в следующем: мы сравниваем контрольные суммы (или итоги) отрезков данных. Весь массив делится пополам. Если контрольные суммы первой половины в обеих базах совпадают, мы эту половину отбрасываем. Если нет — делим ее снова пополам. Этот алгоритм позволяет найти все расхождения за логарифмическое время.

Полное соединение (FULL JOIN) в запросах 1С

Если объемы позволяют загрузить порцию данных во временную таблицу (ВТ), мы можем доверить слияние серверу 1С. Рассмотрим этот подход:

  1. Таблица значений из внешней базы передается порциями (например, через REST API или OData).
  2. Помещаем её во временную таблицу и обязательно индексируем по ключевому полю (УИД или составной ключ).
  3. Делаем запрос с полным соединением ПОЛНОЕ СОЕДИНЕНИЕ к целевой таблице регистра или справочника.
  4. В секции ГДЕ ставим условие на неравенство ресурсов или ЕСТЬ NULL у ключей соединяемых таблиц.

ВЫБРАТЬ
    ЕСТЬNULL(ВнешняяВТ.Ключ, ЛокальнаяТБ.Ключ) КАК Ключ,
    ВнешняяВТ.Сумма КАК СуммаВнешняя,
    ЛокальнаяТБ.Сумма КАК СуммаЛокальная
ИЗ
    ВнешняяТаблица КАК ВнешняяВТ
        ПОЛНОЕ СОЕДИНЕНИЕ ТаблицаБазы КАК ЛокальнаяТБ
        ПО ВнешняяВТ.Ключ = ЛокальнаяТБ.Ключ
ГДЕ
    (ВнешняяВТ.Ключ ЕСТЬ NULL 
    ИЛИ ЛокальнаяТБ.Ключ ЕСТЬ NULL
    ИЛИ ВнешняяВТ.Сумма <> ЛокальнаяТБ.Сумма)

Планы обмена для регрессионного тестирования

Если задача заключается в регулярном регрессионном тестировании, логичнее не сверять все данные заново каждый раз. Разберем по шагам оптимизацию этого процесса:

  1. Настройте ПланыОбмена для фиксации изменений тех объектов, которые затрагивает тест.
  2. Перед началом теста очищайте регистрацию изменений.
  3. После выполнения тестируемого сценария, извлекайте только те записи, которые были зарегистрированы в плане обмена.
  4. Сравнивайте только эту "дельту" (изменившиеся данные) с эталонной выгрузкой. Это радикально снижает нагрузку на систему и ускоряет тесты.

Использование готовых механизмов БСП и СКД

Не забывайте про встроенные инструменты платформы и библиотек. Например, Схема Компоновки Данных (СКД) отлично справляется со слиянием двух внешних наборов данных в оперативной памяти. Вы можете передать две таблицы значений в СКД, связать их и вывести только различающиеся строки.

Также, если данные уже загружены в память в виде коллекций, можно использовать функцию Библиотеки Стандартных Подсистем ОбщегоНазначения.КоллекцииИдентичны(). Она автоматически проверит структуру и содержимое, избавив вас от написания рутинных циклов перебора.

← На главную