Почему запрос к регистру сведений работает медленно и как от него избавиться?

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

Часто в практике разработки на 1С возникает ситуация, когда запрос, который должен выполняться мгновенно, начинает «тормозить». Автор темы столкнулся с классической дилеммой: выполнять 25 запросов в цикле или один запрос с использованием оператора В, который внезапно оказался еще медленнее. Рассмотрим, почему это происходит и как правильно оптимизировать подобные операции.

Разберем причины низкой производительности

Первое, что нужно понимать: использование оператора ГДЕ Поле В (&Массив) не всегда является оптимальным решением. Оптимизатор СУБД (SQL Server) при получении длинного списка значений может построить неэффективный план выполнения. В то время как серия простых запросов, каждый из которых отрабатывает строго по индексу, может показаться быстрее на тестовых объемах данных. Однако это путь к созданию избыточной нагрузки на сеть и сервер.

Основные факторы, влияющие на скорость:

  1. Размерность полей: Поиск по строкам большой длины (например, 150-200 символов) происходит медленнее. Если данные позволяют, всегда сокращайте размерность до реальных значений (например, 80-100 символов).
  2. Отсутствие индексов: Если поля, по которым идет отбор, не индексированы, база данных вынуждена выполнять полное сканирование таблицы.
  3. Актуальность статистики: Устаревшие планы выполнения запросов — частая причина «необъяснимых» тормозов.
  4. Объем выборки: Если вам не нужны все записи, а достаточно нескольких, использование ПЕРВЫЕ критически меняет план запроса, заставляя СУБД остановиться после нахождения нужного количества строк.

Рассмотрим способы оптимизации

Если вы хотите избежать запросов в цикле, но стандартное условие В тормозит, попробуйте использование временных таблиц.

Решение 1: Использование временных таблиц (ВТ)

Вместо передачи массива напрямую, поместите его во временную таблицу, проиндексируйте её и выполните соединение. Это дает оптимизатору четкую подсказку о методе соединения.


// Создаем запрос с использованием ВТ
Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ Имена.ИмяПоля
|ПОМЕСТИТЬ ВТ_Имена
|ИЗ (&СписокИмен) КАК Имена
|;
|ВЫБРАТЬ
|   Регистр.Значение,
|   Регистр.Количество
|ИЗ РегистрСведений.ЗначенияДляПодстановок КАК Регистр
|ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Имена КАК Имена
|ПО Регистр.ИмяПоля = Имена.ИмяПоля
|ГДЕ Регистр.ТипДокумента = &ТипДокумента
|УПОРЯДОЧИТЬ ПО Регистр.Количество УБЫВ";

Решение 2: Использование оператора ПЕРВЫЕ

Если вам нужно получить только наиболее актуальные данные (например, топ-10 самых частых упоминаний), добавьте ключевое слово ПЕРВЫЕ. Это сокращает время выполнения в разы, так как СУБД прекращает поиск после того, как нашла нужное количество записей.

Решение 3: Проверка индексов и статистики

Если производительность все еще остается низкой, выполните следующие шаги:

  1. Проверьте, индексированы ли измерения ТипДокумента и ИмяПоля.
  2. Убедитесь, что порядок измерений в регистре оптимален для ваших отборов.
  3. Обновите статистику базы данных на уровне СУБД. Это сбросит кэшированные планы выполнения, которые могли быть построены для других, менее эффективных условий.

Стоит ли бояться запросов в цикле?

Существует «религия» против запросов в цикле, но важно понимать суть проблемы. Накладные расходы на отправку запроса к серверу при современных скоростях сети зачастую менее значимы, чем построение неоптимального плана выполнения для сложного запроса. Если количество итераций цикла фиксировано и запрос жестко привязан к индексу — это допустимый сценарий. Однако всегда стремитесь к тому, чтобы вынести создание запроса за пределы цикла, меняя в цикле только параметры. Это исключит лишнюю синтаксическую проверку текста запроса платформой.

Заключение: Не поддавайтесь панике при выборе между циклом и одним «тяжелым» запросом. Анализируйте планы запросов с помощью инструментов СУБД, используйте временные таблицы для сложных отборов и не забывайте ограничивать выборку с помощью ПЕРВЫЕ, если вам не требуются все данные сразу.

← На главную