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