Как быстро загрузить большой объем данных из MySQL в 1С 7.7 на MS SQL Server

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При интеграции сторонних веб-сервисов или баз данных на MySQL с платформой 1С:Предприятие 7.7 стандартный перебор через ADODB.Recordset и поэлементная запись штатными объектами 1С вызывают катастрофическое падение производительности на больших объемах данных. Выясним причину этой проблемы и разберем эффективные подходы к ускорению переноса данных напрямую на уровне СУБД и средствами внешних компонент.

Причины низкой скорости при штатном переносе

Когда мы построчно считываем данные через ADO и создаем объекты штатным языком 1С, на каждую запись выполняются десятки служебных операций: сетевые запросы, блокировки таблиц, проверка ссылочной целостности и пересчет служебных таблиц. В результате обработка сотен тысяч строк может занимать многие часы.

Рассмотрим основные варианты оптимизации переноса данных: от настройки транзакций до прямой пакетной вставки через Linked Server и расширение 1С++.

Вариант 1. Пакетная фиксация транзакций в 1С

Если логика загрузки требует обязательного использования штатных методов 1С (например, когда создаются сложные документы с движениями или периодические реквизиты), необходимо минимизировать дисковые операции СУБД за счет группировки в транзакции.

Разберем по шагам, как организовать порционную запись:

  1. Открываем явную транзакцию перед началом пакета записей.
  2. Фиксируем транзакцию каждые 100–1000 записей (оптимальный размер подбирается экспериментально).
  3. Делаем паузу или сброс кэша при необходимости, чтобы не блокировать параллельную работу пользователей.

Посмотрим на пример организации порционной записи:


Счетчик = 0;
РазмерПакета = 500;
НачатьТранзакцию();

Пока ВыборкаMySQL.EOF() = 0 Цикл
    Счетчик = Счетчик + 1;
    
    Спр = СоздатьОбъект("Справочник.Номенклатура");
    // Заполнение реквизитов объекта
    // ...
    Спр.Записать();
    
    Если Счетчик % РазмерПакета = 0 Тогда
        ЗафиксироватьТранзакцию();
        НачатьТранзакцию();
    КонецЕсли;
    
    ВыборкаMySQL.MoveNext();
КонецЦикла;

ЗафиксироватьТранзакцию();

Вариант 2. Связанный сервер (Linked Server) в MS SQL Server

Наиболее быстрое решение — исключить передачу данных через интерфейс 1С и выполнить перенос напрямую между базами данных на уровне MS SQL Server.

Проанализируем шаги настройки связанного сервера:

  1. Устанавливаем на сервере с MS SQL официальный драйвер MySQL Connector/ODBC.
  2. Создаем связанный сервер (Linked Server) через провайдер MSDASQL, указывая параметры подключения к MySQL.
  3. Для выполнения выборки используем функцию OPENQUERY. Это критически важно: OPENQUERY передает запрос на выполнение самому серверу MySQL, снижая нагрузку на сеть и MS SQL Server.

Посмотрим на пример выборки данных через Linked Server:


SELECT * 
FROM OPENQUERY(MYSQL_SERVER, 'SELECT id, article, name, price FROM products WHERE updated_at >= NOW() - INTERVAL 1 DAY');

Архитектурные ограничения прямой записи в таблицы 1С 7.7

При выполнении прямых операций INSERT или UPDATE в таблицы 1С:Предприятия 7.7 необходимо строго учитывать внутреннюю структуру хранения данных:

  1. Формирование идентификаторов (Base36): В 1С 7.7 первичные ключи (поля ID, IDDOC) представляют собой 9-символьные строки в 36-ричной системе счисления. Текущий максимальный идентификатор хранится в системной таблице 1SSYSTEM (поле CURRID). При прямой вставке новых записей обязательно нужно корректно обновлять счетчик в 1SSYSTEM, иначе возникнут дубликаты первичных ключей при штатной работе пользователей.
  2. Системные реквизиты: В таблицах справочников (SC***) обязательно заполняются поля ISMARK, ISFOLDER, PARENTEXT и системный ROW_ID.
  3. Кодировки: База данных 1С 7.7 использует кодировку Windows-1251 (CP1251), тогда как в MySQL данные чаще всего лежат в UTF-8. При вставке обязательно выполняем конвертацию и следим за параметрами COLLATE.

Вариант 3. Использование промежуточной таблицы и компоненты 1С++

Самым надежным и быстрым подходом является двухэтапная схема (Staging):

  1. С помощью Linked Server или утилиты пакетного импорта выгружаем данные из MySQL в отдельную временную (буферную) таблицу внутри MS SQL.
  2. С помощью внешней компоненты 1С++ и объекта ODBCRecordset читаем подготовленные данные прямым SQL-запросом и пакетно обновляем таблицы 1С с использованием метапарсера (макросов типа $Справочник.Номенклатура).

Разберем пример пакетного обновления реквизитов через ODBCRecordset в 1С++:


ЗапросSQL = СоздатьОбъект("ODBCRecordset");
ТекстЗапроса = "
|UPDATE $Справочник.Номенклатура
|SET $Справочник.Номенклатура.Артикул = buf.article,
|    $Справочник.Номенклатура.Цена = buf.price
|FROM $Справочник.Номенклатура AS nom
|INNER JOIN Buffer_MySQL_Products AS buf 
|    ON nom.CODE = buf.code
|WHERE nom.ISMARK = 0
|";
ЗапросSQL.Выполнить(ТекстЗапроса);

Использование связки из Linked Server, промежуточной таблицы и прямых запросов 1С++ позволяет сократить время синхронизации сотен тысяч записей с нескольких часов до нескольких секунд.

← На главную