Как ускорить работу запроса из 1С к большой таблице во внешнем источнике MS SQL?

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

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

Причина медленной работы и создание индекса в СУБД

Выясним причину задержки: когда во внешней таблице MS SQL насчитывается 100+ миллионов строк, а поиск выполняется по полям без подходящего индекса, СУБД вынуждена сканировать всю таблицу целиком (операция Table Scan или Clustered Index Scan). Это приводит к колоссальной нагрузке на дисковую подсистему и процессор сервера.

Для исправления ситуации выполним индексацию полей поиска во внешней базе данных через SQL Server Management Studio (SSMS):

  1. Откроем SQL Server Management Studio и подключимся к внешней базе данных.
  2. Найдем целевую таблицу в обозревателе объектов (Object Explorer).
  3. Создадим новый некластерный индекс (Non-Clustered Index).
  4. Добавим в состав ключа индекса поля, по которым строится условие отбора (например, Номер и Серия). При этом поле с большей селективностью (уникальностью значений) рекомендуется ставить первым.
  5. Если данные могут содержать дубли или некорректные значения, индекс создается как неуникальный (Non-Unique).

Посмотрим на пример DDL-запроса для создания такого индекса в MS SQL Server:


CREATE NONCLUSTERED INDEX [IX_Passports_Number_Series] 
ON [dbo].[InvalidPassports] ([PassNumber] ASC, [PassSeries] ASC);

После создания индекса СУБД перейдет от полного сканирования таблицы к точечному поиску по дереву индекса (операция Index Seek), что сократит время выполнения запроса с минут до долей секунды.

Оптимизация работы с внешними источниками данных со стороны 1С

Проанализируем правила взаимодействия платформы 1С с внешними источниками данных (ВИД), которые необходимо соблюдать для максимального быстродействия:

  1. Отказ от прямых соединений (JOIN) внутренних таблиц 1С и внешних источников: Если в одном запросе 1С объединяется внутренняя таблица (например, справочник Справочник.ФизическиеЛица) и таблица внешнего источника данных, внешняя СУБД не может выполнить соединение на своей стороне. Платформа 1С будет выгружать данные на сервер 1С и соединять их во временных таблицах. Чтобы исключить падение производительности, выборку из внешнего источника следует выполнять отдельным запросом.
  2. Пакетная проверка вместо запросов в цикле: Выполнение единичных запросов в цикле порождает постоянные сетевые задержки (network round-trip). Сформируем массив проверяемых значений и передадим их в один запрос с условием ГДЕ (Поле1, Поле2) В (&СписокЗначений).
  3. Обязательная параметризация: Все отборы должны передаваться строго через параметры объекта Запрос. Это позволяет MS SQL Server кэшировать скомпилированный план выполнения (Execution Plan) и повторно использовать его при последующих вызовах.

Посмотрим на пример правильной организации пакетного запроса к таблице внешнего источника данных в коде 1С:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ВнешняяТаблица.Серия КАК Серия,
    |	ВнешняяТаблица.Номер КАК Номер
    |ИЗ
    |	ВнешнийИсточникДанных.ВнешняяБД.Таблица.НедействительныеПаспорта КАК ВнешняяТаблица
    |ГДЕ
    |	(ВнешняяТаблица.Номер, ВнешняяТаблица.Серия) В (&СписокДокументов)";

Запрос.УстановитьПараметр("СписокДокументов", МассивПараметров);
Результат = Запрос.Выполнить().Выгрузить();

Дополнительные методы оптимизации на уровне MS SQL Server

Если таблица содержит сотни миллионов строк и активно растет, рассмотрим дополнительные инженерные решения на стороне СУБД:

  1. Оптимизация типов данных: Использование строковых типов (VARCHAR, NVARCHAR) для хранения числовых реквизитов существенно раздувает размер индекса. Объединение серии и номера в единое целочисленное поле типа BIGINT уменьшает индекс в несколько раз, позволяя ему целиком помещаться в оперативной памяти (Buffer Pool).
  2. Сжатие данных (Page/Row Compression): Включение сжатия страниц (PAGE Compression) для таблицы и некластерного индекса снижает объем дискового ввода-вывода и ускоряет чтение данных.
  3. Секционирование (Partitioning): Разделение таблицы на секции по диапазонам позволяет СУБД отсекать нерелевантные разделы при поиске (Partition Elimination).
  4. Таблицы в памяти (In-Memory OLTP): Если таблица используется преимущественно для чтения, перевод структуры в формат MEMORY_OPTIMIZED обеспечивает время отклика в микросекунды.

Архитектурные альтернативы при высоких нагрузках

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

  1. Использование вероятностных структур (Фильтр Блума): При проверке на вхождение в «черные списки» большинство записей являются валидными. Фильтр Блума (Bloom Filter), инициализированный в памяти сервиса, занимает десятки мегабайт и позволяет со 100% точностью подтвердить отсутствие записи без обращения к СУБД.
  2. Вынос данных в Key-Value хранилища (Redis): Использование структур Set или битовых карт в Redis гарантирует мгновенную проверку наличия ключа под любой параллельной нагрузкой.
  3. Микросервисный слой: Вместо прямого подключения платформы 1С через ВИД создается легковесный HTTP-сервис, который управляет пулом подключений или держит кэш в оперативной памяти, возвращая результат проверки в 1С по протоколу REST.
← На главную