Часто в практике разработки на 1С возникает ситуация, когда запрос, который должен выполняться мгновенно, начинает «тормозить». Автор темы столкнулся с классической дилеммой: выполнять 25 запросов в цикле или один запрос с использованием оператора В, который внезапно оказался еще медленнее. Рассмотрим, почему это происходит и как правильно оптимизировать подобные операции.
Первое, что нужно понимать: использование оператора ГДЕ Поле В (&Массив) не всегда является оптимальным решением. Оптимизатор СУБД (SQL Server) при получении длинного списка значений может построить неэффективный план выполнения. В то время как серия простых запросов, каждый из которых отрабатывает строго по индексу, может показаться быстрее на тестовых объемах данных. Однако это путь к созданию избыточной нагрузки на сеть и сервер.
Основные факторы, влияющие на скорость:
ПЕРВЫЕ критически меняет план запроса, заставляя СУБД остановиться после нахождения нужного количества строк.Если вы хотите избежать запросов в цикле, но стандартное условие В тормозит, попробуйте использование временных таблиц.
Вместо передачи массива напрямую, поместите его во временную таблицу, проиндексируйте её и выполните соединение. Это дает оптимизатору четкую подсказку о методе соединения.
// Создаем запрос с использованием ВТ
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ Имена.ИмяПоля
|ПОМЕСТИТЬ ВТ_Имена
|ИЗ (&СписокИмен) КАК Имена
|;
|ВЫБРАТЬ
| Регистр.Значение,
| Регистр.Количество
|ИЗ РегистрСведений.ЗначенияДляПодстановок КАК Регистр
|ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Имена КАК Имена
|ПО Регистр.ИмяПоля = Имена.ИмяПоля
|ГДЕ Регистр.ТипДокумента = &ТипДокумента
|УПОРЯДОЧИТЬ ПО Регистр.Количество УБЫВ";
Если вам нужно получить только наиболее актуальные данные (например, топ-10 самых частых упоминаний), добавьте ключевое слово ПЕРВЫЕ. Это сокращает время выполнения в разы, так как СУБД прекращает поиск после того, как нашла нужное количество записей.
Если производительность все еще остается низкой, выполните следующие шаги:
ТипДокумента и ИмяПоля.Существует «религия» против запросов в цикле, но важно понимать суть проблемы. Накладные расходы на отправку запроса к серверу при современных скоростях сети зачастую менее значимы, чем построение неоптимального плана выполнения для сложного запроса. Если количество итераций цикла фиксировано и запрос жестко привязан к индексу — это допустимый сценарий. Однако всегда стремитесь к тому, чтобы вынести создание запроса за пределы цикла, меняя в цикле только параметры. Это исключит лишнюю синтаксическую проверку текста запроса платформой.
Заключение: Не поддавайтесь панике при выборе между циклом и одним «тяжелым» запросом. Анализируйте планы запросов с помощью инструментов СУБД, используйте временные таблицы для сложных отборов и не забывайте ограничивать выборку с помощью ПЕРВЫЕ, если вам не требуются все данные сразу.