Оптимизация использования оперативной памяти
Неоднократно попадались вопросы на собеседованиях типа "что тут не так в коде" и там какой-нибудь запрос с "Запрос.Выполнить().Выгрузить()" к какому-нибудь огромному справочнику. И вот тут есть засада, так как первым делом хочется сказать, что нужно делать через выборку, а не тут-то было... Согласно стандартам и тот и тот вариант будут не корректными.
#std725
2. При потенциально неограниченных выборках данных из ИБ следует получать данные из базы порциями фиксированного размера.
Например, неправильно:
...
Номенклатура = Запрос.Выполнить().Выгрузить();
Для каждого ПозицияНоменклатуры Из Номенклатура Цикл
...
Также неправильно:
....
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
...
РезультатЗапроса = Запрос.Выполнить();
// Обход результата запроса
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
....
Второй вариант близок к истине, но без искусственного ограничения на "ВЫБРАТЬ ПЕРВЫЕ 1000" это не имеет смысла.
#std725
Правильно ограничивать результат запроса искусственно:
ВсеОбработано = Ложь;
Пока Истина Цикл
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1000
| Номенклатура.Ссылка,
....
// Обход порции результата запроса
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Обработка элемента выборки
// ...
КонецЦикла;
КонецЦикла;
Если сделать первыми двумя неправильными вариантами, то это приведет к тормозам из-за нехватки памяти, а возможно и к полному зависанию системы. А в корректном варианте данные будут выбираться порционно.
Также есть ещё один правильный вариант с отбором выборки: "Выборка = Справочники.Номенклатура.Выбрать(..., Отбор);"
P.S. Полное описание стандарта по ссылке в начале поста
#ЧёПоСтандартам #std725