Очень часто наблюдал, как при решении задач разработчики используют выгрузку результатов запроса в таблицу значений, а затем выполняют обработку данных уже в ней. Использование такого подхода неоптимально с точки зрения производительности, поскольку выполняется лишнее действие по формированию таблицы значений в оперативной памяти, что дополнительно нагружает машину и, соответственно, увеличивает время выполнения алгоритма.
Проведем два небольших теста на справочнике "Товары" в тестовой конфигурации. В нем содержатся чуть больше 500.000 записей. В обоих вариантах теста будем выводить имена всех элементов с помощью метода "Сообщить()".
В первом варианте для решения поставленной задачи напишем следующий программный код:
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Товары.Ссылка, | Товары.ВерсияДанных, | Товары.ПометкаУдаления, | Товары.Предопределенный, | Товары.Родитель, | Товары.ЭтоГруппа, | Товары.Код, | Товары.Наименование, | Товары.Артикул |ИЗ | Справочник.Товары КАК Товары |ГДЕ | Товары.Ссылка В ИЕРАРХИИ(&ОтборПоТоварам)"; Запрос.УстановитьПараметр("ОтборПоТоварам", ОтборПоТоварам); Результат = Запрос.Выполнить(); ТаблицаРезультат = Результат.Выгрузить(); // Выгружаем результат запроса в таблицу значений Для Каждого Эл Из ТаблицаРезультат Цикл Сообщить("Это элемент: " + Эл.Ссылка); КонецЦикла;
Замерив с помощью стандартного инструмента "Замер производительности" время выполнения прграммного кода, мы получим следующий результат:
Время выполнения составило ~160 секунд. При этом метод "Выгрузить()" выполнялся 5,6 секунд (3 строка в таблице результата). Выполним другой тест без использования выгрузки результата запроса в таблицу значений.
Решим ту же задачу без использования выгрузки результата запроса в таблицу значений. Алгоритм в таком случае будет выглядить следующим образом:
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Товары.Ссылка, | Товары.ВерсияДанных, | Товары.ПометкаУдаления, | Товары.Предопределенный, | Товары.Родитель, | Товары.ЭтоГруппа, | Товары.Код, | Товары.Наименование, | Товары.Артикул |ИЗ | Справочник.Товары КАК Товары |ГДЕ | Товары.Ссылка В ИЕРАРХИИ(&ОтборПоТоварам)"; Запрос.УстановитьПараметр(ОтборПоТоварам, ОтборПоТоварам); Результат = Запрос.Выполнить(); Выборка = Результат.Выбрать(); // Получаем выборку результата запроса Пока Выборка.Следующий() Цикл Сообщить(Это элемент + Выборка.Ссылка); КонецЦикла;
Замерив время выполнения получим следующий результат:
Результат очевиден. Скорость выполнения алгоритма возросла. Время составило ~153,7 секунды. Проанализируем результаты обоих тестов.
Сравнив два результата проведенных тестов невооруженным глазом можно увидеть, что выгрузка результата запроса снижает скорость выполнения программного кода. Степень влияния на производительность зависит от машины, на котором установлена платформа/сервер 1С. В нашем конкретном случае время выполнения алгоритма с выгрузкой результата запроса в таблицу значений больше на 6,86 секунды, или на 4,5 %.
В рамках текущего примера это может показаться незначительным изменением, однако если посмотреть на это в случае многопользовательской системы, то изменение будет весьма критичным. С учетом того, что в типовой конфигурации "Управление производственным предприятием" практически во всех алгоритмах проведения документов происходит выгрузка наборов записей для каждого из регистров, по которым делается движение, то снижение производительности может быть весьма значительным.
Наиболее оптимально обрабатывать данные обходя выборку запроса, как это было показано во втором тесте. Тогда мы сможем ускорить время выполнения алгоритма и использованную оперативную память.