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

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

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

Выясним причину: почему запросы к регистрам работают медленно

Прежде чем приступать к написанию кода, проанализируем ситуацию и поймем, как платформа взаимодействует с СУБД. Основная нагрузка при выполнении запроса ложится на дисковую подсистему и оперативную память сервера SQL. Рассмотрим основные факторы, влияющие на скорость:

  1. Отсутствие подходящих индексов: Если в условии запроса используются поля, не входящие в состав ведущих измерений или не проиндексированные вручную, СУБД приходится выполнять полное сканирование таблицы (Index Scan или Table Scan).
  2. Неправильное использование виртуальных таблиц: Обращение к СрезПоследних без параметров (без отбора по периоду и измерениям) заставляет систему обрабатывать весь объем данных регистра.
  3. Запросы в цикле: Выполнение даже самого быстрого запроса внутри цикла Для Каждого порождает лавинообразный рост нагрузки на сервер.
  4. Соединения с подзапросами: Использование подзапросов в блоке СОЕДИНЕНИЕ лишает оптимизатор СУБД возможности эффективно использовать индексы.

Разберем по шагам: использование временных таблиц для оптимизации

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


// Создаем менеджер временных таблиц
МенеджерВТ = Новый МенеджерВременных Таблиц;
Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

// Шаг 1: Подготовка исходных данных
Запрос.Текст = 
"ВЫБРАТЬ
|	Товары.Ссылка КАК Номенклатура
|ПОМЕСТИТЬ ВТ_Номенклатура
|ИЗ
|	Справочник.Номенклатура КАК Товары
|ГДЕ
|	Товары.ЭтоГруппа = ЛОЖЬ";

Запрос.Выполнить();

Важный момент: использование временных таблиц позволяет платформе 1С создать реальные временные таблицы на стороне SQL-сервера и построить по ним индексы автоматически (если объем данных велик). Это значительно ускоряет последующие соединения с физическими таблицами регистров.

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

Проанализируем типичную ошибку при получении цен или остатков. Часто разработчики накладывают условия в блоке ГДЕ, что является критической ошибкой для производительности. Рассмотрим правильный подход, используя параметры виртуальной таблицы.


Запрос.Текст = 
"ВЫБРАТЬ
|	Цены.Номенклатура,
|	Цены.Цена
|ИЗ
|	РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, Номенклатура В (ВЫБРАТЬ Номенклатура ИЗ ВТ_Номенклатура)) КАК Цены";

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

В данном примере мы передаем условие фильтрации напрямую в параметры виртуальной таблицы СрезПоследних. Это позволяет системе 1С сформировать SQL-запрос, который отсечет ненужные записи на самом раннем этапе выполнения, не зачитывая весь регистр в память.

Работа с индексами: что нужно знать разработчику

Выясним, как работают индексы в 1С. По умолчанию платформа создает индекс по всем измерениям в порядке их следования в метаданных. Если вы часто ищете данные по измерению Организация, но оно стоит третьим в списке, индекс может не сработать. Для решения этой проблемы разберем следующие рекомендации:

  1. Порядок измерений: Ставьте наиболее селективные измерения (те, по которым данные распределены максимально разнообразно) в начало списка.
  2. Свойство "Индексировать": Если вам необходимо часто искать данные по ресурсу или реквизиту (что нетипично, но бывает), установите у этого поля свойство Индексировать или Индексировать с доп. упорядочиванием.
  3. Уникальность: Помните, что для периодических регистров сведений платформа создает уникальный индекс, включающий Период, измерения и НомерСтроки (если применимо).

Анализируем использование конструкции ВЫБРАТЬ ПЕРВЫЕ

Иногда нам не нужно получать все записи, достаточно проверить наличие хотя бы одной. Посмотрим, как это сделать максимально эффективно, не нагружая сервер. Мы будем использовать ВЫБРАТЬ ПЕРВЫЕ 1 в сочетании с правильной сортировкой.


Запрос.Текст = 
"ВЫБРАТЬ ПЕРВЫЕ 1
|	1 КАК Поле1
|ИЗ
|	РегистрСведений.ИсторияСтатусов КАК Статусы
|ГДЕ
|	Статусы.Объект = &Объект
|	И Статусы.Статус = &ИскомыйСтатус";

Запрос.УстановитьПараметр("Объект", ДокументСсылка);
Запрос.УстановитьПараметр("ИскомыйСтатус", Перечисления.Статусы.Активен);

Если НЕ Запрос.Выполнить().Пустой() Тогда
    // Обработка логики
КонецЕсли;

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

Заключение и выводы

Мы проанализировали основные методы оптимизации работы с регистрами сведений в 1С. Подведем итоги совместной работы:

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

← На главную