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

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

Работа с динамическими списками в 1С — это удобный инструмент для отображения больших массивов данных. Однако разработчики часто сталкиваются с ситуацией, когда обычный скроллинг списка работает приемлемо, но попытка выполнить стандартную команду «Вывести список» приводит к «мертвому» зависанию системы и резкому росту потребления оперативной памяти процессом rphost. Проанализируем, почему это происходит, и разберем по шагам методы оптимизации системы.

Различие механизмов отображения и вывода списка

Для начала выясним причину, по которой запрос в консоли выполняется быстро, а вывод списка «умирает». Динамический список при обычном отображении на форме работает в режиме порционного чтения. Он запрашивает ровно столько записей, сколько нужно для заполнения текущего экрана (обычно от 20 до 45 строк). В этот момент СУБД использует быстрые индексы, и нагрузка минимальна.

Когда же мы нажимаем «Вывести список», платформа переключается в совершенно другой режим. Она пытается получить все данные выборки сразу. При этом динамический список фактически переинициализируется внутри системы компоновки данных (СКД). Если ваш произвольный запрос содержит сложные соединения, вложенные запросы или обращения к виртуальным таблицам, СКД может перестроить его таким образом, что план выполнения на стороне SQL-сервера станет крайне неэффективным.

Проблема сложных соединений и вложенных запросов

Рассмотрим типичную ситуацию: к основной таблице (например, регистру сведений) присоединяются данные из других таблиц через вложенные запросы. Если связь идет по составным полям, это является главной точкой отказа.

Проанализируем ситуацию: на уровне SQL-запроса соединение по составному полю (например, ЛюбаяСсылка) превращается в громоздкую конструкцию из CASE и множества LEFT JOIN ко всем возможным таблицам, входящим в этот тип. При выводе 8 000 записей это может привести к генерации временных таблиц объемом в сотни мегабайт, которые rphost будет пытаться переварить в памяти.

Решение: необходимо максимально упростить запрос. Вместо вложенных запросов старайтесь использовать прямые соединения с таблицами. Если соединение по составному полю неизбежно, обязательно используйте типизацию через ВЫРАЗИТЬ.

Пример оптимизации поля связи:


// Неоптимально:
ВЫБРАТЬ
    Регистр.Заказ,
    ДопДанные.Значение
ИЗ
    РегистрСведений.ОсновныеДанные КАК Регистр
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеДанные КАК ДопДанные
    ПО Регистр.Заказ = ДопДанные.Заказ

// Оптимально (если Заказ - составной тип):
ВЫБРАТЬ
    Регистр.Заказ,
    ДопДанные.Значение
ИЗ
    РегистрСведений.ОсновныеДанные КАК Регистр
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеДанные КАК ДопДанные
    ПО ВЫРАЗИТЬ(Регистр.Заказ КАК Документ.ЗаказПокупателя) = ДопДанные.Заказ

Влияние обработчиков событий представления

Выясним еще одну скрытую причину зависания — формирование текстовых представлений ссылочных объектов. Даже если в вашем запросе нет явных функций ПРЕДСТАВЛЕНИЕ(), платформа 1С при выводе в табличный документ обязана получить текст для каждой ссылки.

Если для какого-либо справочника, используемого в списке, определена процедура ОбработкаПолученияПредставления в модуле менеджера, она будет вызвана для каждой строки при выводе списка. Если внутри этой процедуры есть запросы к базе данных, то при выводе 7 000 строк вы получите 7 000 дополнительных микро-запросов, что гарантированно приведет к зависанию.

Посмотрим, как проверить наличие этого обработчика. Нужно открыть модуль менеджера соответствующего объекта метаданных и найти процедуру:


Процедура ОбработкаПолученияПредставления(Данные, Представление, СтандартнаяОбработка)
    // Если здесь есть сложные вычисления или запросы - это причина тормозов
КонецПроцедуры

Настройка ключа динамического списка

Разберем ситуацию, когда при скроллинге данные «пропадают» или отображается меньше записей, чем есть на самом деле. Это явный признак проблемы с уникальностью ключа строки. Динамический список использует набор полей основной таблицы для идентификации строк. Если ваш запрос из-за JOIN дублирует строки, или если свойство Основная таблица не указано/указано неверно, платформа начинает «схлопывать» записи.

Проанализируем шаги для исправления:

  1. Убедитесь, что в свойствах динамического списка заполнено поле Основная таблица. Это позволяет платформе использовать оптимизированные запросы и правильно определять ключи.
  2. Если используется произвольный запрос с объединениями, проверьте, чтобы результирующий набор содержал уникальный идентификатор (например, Ссылка или комбинация измерений регистра).
  3. В настройках списка (закладка «Настройка списка» в конфигураторе) можно явно указать Ключ строки, выбрав поля, гарантирующие уникальность.

Особенности платформы и замер производительности

Если вы работаете на платформе версии 8.3.10 или близких к ней, помните о возможных утечках памяти при работе СКД. В старых версиях механизмы кэширования представлений работали менее эффективно. Рассмотрим, как локализовать проблему с помощью инструментов платформы.

Для диагностики используйте Замер производительности. Несмотря на то, что динамический список работает «внутри» платформы, выполнение команды «Вывести список» инициирует серверные вызовы. Включите замер, выполните команду (подождите немного) и прервите выполнение. В результатах замера вы сможете увидеть, на каких участках (например, при получении представлений) тратится больше всего времени.

Рекомендации по ускорению вывода

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

Соблюдение этих правил позволит сделать работу ваших пользователей комфортной, а вывод даже больших списков — предсказуемым и быстрым.

← На главную