Разработчики часто сталкиваются с ситуацией, когда оптимизированный запрос, выполняющийся за считанные секунды в консоли, при переносе в систему компоновки данных (СКД) начинает работать в разы дольше. Давайте разберем, почему это происходит и как последовательно диагностировать и устранить эту проблему.
Первым делом нужно понять, где именно «застревает» отчет: на этапе выполнения запроса к базе данных или на этапе формирования табличного документа. Попробуйте вывести результат не в ТабличныйДокумент, а в ТаблицуЗначений программно. Если время выполнения при выводе в ТаблицуЗначений значительно меньше, значит, основной ресурс тратится на оформление и отрисовку ячеек. Если время практически не изменилось — проблема кроется именно в процессе формирования выборки данных движком СКД.
СКД — это не просто «обертка» над запросом. Система активно вмешивается в ваш SQL-код, добавляя дополнительные поля для группировок, представлений и связей. Чтобы увидеть реальный запрос, который «уходит» в СУБД, выполните следующие действия:
Технологический Журнал с настроенным событием SDBL или DBMSSQL для захвата реального запроса.Часто вы обнаружите, что СКД добавила множество левых соединений для автоматического получения представлений полей, что катастрофически снижает производительность.
Роли полей в СКД определяют, как данные будут участвовать в механизмах компоновки. Если поле добавлено в набор данных, но не используется в группировках, снимите с него все роли, установив их значение в Нет. Избыточные роли заставляют систему выполнять дополнительные операции сортировки и соединения, даже если визуально вы не используете эти поля в отчете.
Если в вашем запросе используются виртуальные таблицы, убедитесь, что параметры (например, Период или условия отбора) передаются в них корректно. Если вы укажете параметры в секции ГДЕ основного запроса, а не в параметрах виртуальной таблицы, SQL-сервер будет вынужден сначала выбрать все данные из таблицы, а уже потом отфильтровать их. Это может привести к полному сканированию огромных таблиц (Table Scan). Проверьте план выполнения запроса в SQL Server Management Studio — наличие Table Scan или Index Scan там, где должен быть Index Seek, — это сигнал к действию.
Если запрос очень сложный и состоит из множества соединений, попробуйте упростить его логику, используя ВременныеТаблицы в самом тексте запроса. СКД будет работать с уже «свернутыми» данными, что значительно сократит количество операций, выполняемых движком компоновки. Если запрос очень тяжелый, можно использовать подход с созданием промежуточной таблицы:
// Пример логики подготовки данных
ВЫБРАТЬ
Данные.Поле1,
Данные.Поле2
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
ТаблицаДанных КАК Данные
;
ВЫБРАТЬ * ИЗ ВременнаяТаблица
Это заставляет движок СУБД подготовить данные до того, как за них возьмется СКД.
Автоматическое получение представлений — частый «убийца» производительности. Если в выборке есть поля ссылочного типа, СКД пытается «дотянуться» до каждого объекта, чтобы получить его строковое представление. Попробуйте в запросе обращаться к нужному полю явно, например: Контрагент.Наименование вместо обращения к полю Контрагент. Также можно попробовать программно отключить получение представлений для конкретных полей, если это позволяет архитектура отчета.
Если ничего не помогает, используйте стратегию последовательного отключения частей запроса:
Помните: оптимизация — это всегда поиск баланса между функциональностью СКД и мощностью SQL-сервера. Иногда проще подготовить данные заранее в фоновом режиме, чем заставлять СКД вычислять «на лету» сложные выборки из 20 тысяч строк с множеством соединений.