Оптимизация СКД в 1С: как находить ошибки и ускорять отчеты
Контекст и ситуация
Специалист с 5-летним опытом знает, что СКД генерирует запрос автоматически. Но мало кто задумывается: как именно платформа строит ГДЕ и СВЯЗИ при наличии отборов по полям из разных наборов данных? Типичная картина — отчет работал минуту, после добавления одного отбора стал «виснуть» на 10 минут. В справке 1С описано, что СКД использует вложенные запросы для отборов по детальным записям, но нет ни слова о том, что это приводит к декартову произведению во временных таблицах, если неверно настроены связи между наборами.
Технический разбор: почему СКД «тормозит» на отборах
Разберем механику. Когда в отчете СКД есть два набора данных (например, «Шапки» и «Товары») и пользователь устанавливает отбор по полю из набора «Товары» (например, Номенклатура.Наименование), СКД не добавляет условие в ГДЕ основного запроса к «Шапкам». Вместо этого она создает вложенный запрос, который джойнит оба набора, и отбор применяется уже к результату этого джойна. Если связь между наборами задана как «левый джойн», а индекс по полю связи отсутствует — СКД начинает табличный сканирование с формированием временной таблицы, содержащей все возможные комбинации строк. Для 50 000 документов по 20 строк каждый — это миллион записей во временной таблице.
Ловушка: СКД не умеет «проталкивать» отборы по детальным записям в подчиненный запрос при наличии агрегатных функций или группировок в основном наборе. Она всегда делает внешнее соединение перед отбором.
Практическое руководство: три метода борьбы
1. Разрыв связи вручную через вычисляемые поля
Вместо того чтобы использовать стандартную связь между наборами «Шапки - Товары», создайте единый запрос с явным ОБЪЕДИНИТЬ ВСЕ и выносите отбор в ГДЕ этого общего запроса. Но это убивает гибкость СКД. Альтернатива — добавить в набор «Шапки» вычисляемое поле, которое через ВЫРАЗИТЬ и подзапрос агрегирует нужные данные из детальных записей (например, список GUID номенклатур через ВЫБОР КОГДА). Тогда отбор по номенклатуре будет работать на уровне ГДЕ основного запроса.
// В схеме СКД, набор "Шапки", вычисляемое поле "СписокТоваров"
// Выражение: ВЫРАЗИТЬ(ВЫБОР КОГДА Товары.Номенклатура ССЫЛКА Справочник.Номенклатура
// ТОГДА Значение(Справочник.Номенклатура.ПустаяСсылка) ИНАЧЕ Товары.Номенклатура КОНЕЦ КАК СТРОКА(250))
// Поле используется ТОЛЬКО для отбора, не для вывода
2. Принудительное использование временных таблиц в запросе
Если отчет работает на СКД, но имеет сложную схему с 3+ наборами, перепишите основной запрос набора данных так, чтобы он сам формировал временную таблицу (ПОМЕСТИТЬ ВТ) с предварительно отфильтрованными данными. СКД будет джойнить уже эту урезанную таблицу.
// Вместо прямого запроса к документам
ВЫБРАТЬ
Док.Ссылка,
Док.Дата
ПОМЕСТИТЬ ВТ_ДокументыФильтр
ИЗ
Документ.РеализацияТоваровУслуг КАК Док
ГДЕ
Док.Дата МЕЖДУ &НачПериода И &КонПериода
;
// Основной запрос СКД уже берет из ВТ
ВЫБРАТЬ
ВТ.Ссылка,
ВТ.Дата,
Тов.Номенклатура
ИЗ
ВТ_ДокументыФильтр КАК ВТ
ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг.Товары КАК Тов
ПО ВТ.Ссылка = Тов.Ссылка
Важно: При таком подходе пользовательские отборы из СКД (диапазон дат и т.д.) придется передавать как параметры запроса в ВТ. Иначе СКД наложит свой отбор поверх уже отфильтрованной ВТ, что не дает ускорения.
3. Исправление ошибок при использовании «Внешних наборов» с пакетными запросами
Частая ошибка — попытка передать в СКД таблицу значений через ВнешниеНаборыДанных и при этом оставить в схеме отбор по полю этой таблицы. СКД в таком случае не может перестроить запрос, и фактически отбор выполняется на стороне 1С после получения всех данных. Решение: либо предварительно фильтровать таблицу значений перед передачей в СКД, либо добавлять ВТ непосредственно в текст запроса набора данных, а не через внешние источники.
Типичные ошибки и чек-лист
| Ошибка | Последствие | Решение |
|---|---|---|
| Отбор по полю из детального набора при наличии аггрегации в основном | Декартово произведение во временной таблице | Вынести отбор внутрь запроса через ВТ (метод 2) |
Использование ВнешниеНаборыДанных без предварительной фильтрации |
Фильтрация на клиенте — тормоза при 100 000+ строк | Фильтровать до установки в СКД или перейти на ВТ |
| Связь наборов по полям, не входящим ни в один индекс | Полный перебор таблиц в СУБД | Добавить индексы или изменить тип связи на ВНУТРЕННЕЕ где возможно |
Что делать прямо сейчас
- Профилируйте отчет: включите в конфигурации
Технологический журналс фильтромСКДиDBMS. Посмотрите, какие запросы генерирует СКД — если видитеSELECT ... FROM (SELECT ...) AS QRY_1 ... WHERE ...с вложенностью более 2 уровней — вы поймали проблему. - Проверьте связи: откройте схему СКД, вкладка «Наборы данных», посмотрите на связи. Если связь между наборами содержит поля из левой таблицы, которые не являются ключами — перепишите запрос набора данных, добавив
ВТдля левой таблицы. - Отключайте автозаполнение полей: на вкладке «Параметры» СКД снимите галочку «Автозаполнение выбранных полей» — это заставит вас явно указывать поля, исключив случайное добавление неиспользуемых колонок, которые утяжеляют запрос.
- Используйте
ВЫРАЗИТЬдля отборов: если отбор по полю из детального набора критичен, добавьте в основной набор вычисляемое поле с выражением, которое через подзапрос получает агрегированное значение (например, количество уникальных номенклатур), и отбор ставьте на это вычисляемое поле — он уйдет вГДЕосновного запроса.
Ключевое правило: СКД — не блэкбокс. Откройте «Отчет о выполнении» (в режиме толстого клиента — Ctrl+Shift+O) и смотрите реальный SQL-текст, который уходит в СУБД. Если он содержит вложенные запросы по полной таблице без фильтрации — вы держите в руках причину тормозов.
Заключение
Оптимизация СКД — это не магия, а понимание того, как платформа транслирует визуальные настройки в текст запроса к СУБД. Основная ловушка — иллюзия, что СКД «сама всё оптимизирует». На деле она выбирает универсальный, но часто неэффективный путь. Три описанных метода — разрыв связей через вычисляемые поля, принудительные временные таблицы и отказ от внешних наборов с фильтрацией на стороне 1С — покрывают 90% реальных проблем производительности. Используйте их системно, а не от случая к случаю.
Статья подготовлена по материалам исследования производительности СКД в типовых конфигурациях на платформе 8.3.2x. Проверено на стендах с объемами данных 500 000+ документов.
Попробовать НОПик →