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

Программист 1С v8.3 (Обычные формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Шаг 1: Изоляция проблемы вывода

Первым делом нужно понять, где именно «застревает» отчет: на этапе выполнения запроса к базе данных или на этапе формирования табличного документа. Попробуйте вывести результат не в ТабличныйДокумент, а в ТаблицуЗначений программно. Если время выполнения при выводе в ТаблицуЗначений значительно меньше, значит, основной ресурс тратится на оформление и отрисовку ячеек. Если время практически не изменилось — проблема кроется именно в процессе формирования выборки данных движком СКД.

Шаг 2: Анализ запроса, сгенерированного СКД

СКД — это не просто «обертка» над запросом. Система активно вмешивается в ваш SQL-код, добавляя дополнительные поля для группировок, представлений и связей. Чтобы увидеть реальный запрос, который «уходит» в СУБД, выполните следующие действия:

  1. Перенесите настройки вашего отчета в консоль компоновки данных.
  2. Воспользуйтесь механизмом получения текста запроса, который формирует компоновщик.
  3. Используйте Технологический Журнал с настроенным событием SDBL или DBMSSQL для захвата реального запроса.

Часто вы обнаружите, что СКД добавила множество левых соединений для автоматического получения представлений полей, что катастрофически снижает производительность.

Шаг 3: Оптимизация ролей полей

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

Шаг 4: Устранение проблемы с виртуальными таблицами

Если в вашем запросе используются виртуальные таблицы, убедитесь, что параметры (например, Период или условия отбора) передаются в них корректно. Если вы укажете параметры в секции ГДЕ основного запроса, а не в параметрах виртуальной таблицы, SQL-сервер будет вынужден сначала выбрать все данные из таблицы, а уже потом отфильтровать их. Это может привести к полному сканированию огромных таблиц (Table Scan). Проверьте план выполнения запроса в SQL Server Management Studio — наличие Table Scan или Index Scan там, где должен быть Index Seek, — это сигнал к действию.

Шаг 5: Использование временных таблиц

Если запрос очень сложный и состоит из множества соединений, попробуйте упростить его логику, используя ВременныеТаблицы в самом тексте запроса. СКД будет работать с уже «свернутыми» данными, что значительно сократит количество операций, выполняемых движком компоновки. Если запрос очень тяжелый, можно использовать подход с созданием промежуточной таблицы:


// Пример логики подготовки данных
ВЫБРАТЬ
    Данные.Поле1,
    Данные.Поле2
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
    ТаблицаДанных КАК Данные
;
ВЫБРАТЬ * ИЗ ВременнаяТаблица

Это заставляет движок СУБД подготовить данные до того, как за них возьмется СКД.

Шаг 6: Отключение автоматического получения представлений

Автоматическое получение представлений — частый «убийца» производительности. Если в выборке есть поля ссылочного типа, СКД пытается «дотянуться» до каждого объекта, чтобы получить его строковое представление. Попробуйте в запросе обращаться к нужному полю явно, например: Контрагент.Наименование вместо обращения к полю Контрагент. Также можно попробовать программно отключить получение представлений для конкретных полей, если это позволяет архитектура отчета.

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

Если ничего не помогает, используйте стратегию последовательного отключения частей запроса:

  1. Отключите все соединения, оставив одну основную таблицу. Замерьте время.
  2. Добавляйте по одной таблице в соединения.
  3. Если на определенном этапе время выполнения резко возрастает, значит, именно это соединение или структура связей является узким местом.

Помните: оптимизация — это всегда поиск баланса между функциональностью СКД и мощностью SQL-сервера. Иногда проще подготовить данные заранее в фоновом режиме, чем заставлять СКД вычислять «на лету» сложные выборки из 20 тысяч строк с множеством соединений.

← На главную