При работе с регистром бухгалтерии Хозрасчетный программисты часто сталкиваются с существенным замедлением системы при использовании виртуальной таблицы ДвиженияССубконто. Это происходит из-за того, что на уровне СУБД эта таблица представляет собой сложное соединение основной таблицы движений с таблицами значений субконто. В данной статье мы разберем, как оптимизировать такие запросы, проанализируем типичные ошибки и рассмотрим альтернативные подходы к получению данных.
Одной из самых частых причин медленной работы является обращение к реквизитам субконто через «точку», например: СубконтоКт3.УпрСтатьяБДР. Поскольку поле Субконто имеет составной тип данных, система 1С вынуждена выполнять LEFT JOIN со всеми таблицами справочников, которые могут выступать в роли этого субконто. Если в плане счетов для данного вида субконто разрешено множество типов, количество соединений в SQL-запросе может исчисляться десятками.
Рассмотрим, как правильно ограничить типы данных. Для этого мы должны использовать функцию ВЫРАЗИТЬ. Проанализируем пример кода:
|ВЫБРАТЬ
| ФактБухгалтерия.Период,
| ВЫРАЗИТЬ(ФактБухгалтерия.СубконтоКт3 КАК Справочник.СтатьиДоходовИРасходов).УпрСтатьяБДР КАК Статья
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто(&ДатаНач, &ДатаКон, ...) КАК ФактБухгалтерия
Использование ВЫРАЗИТЬ жестко указывает платформе, с какой конкретно таблицей нужно выполнить соединение, что значительно сокращает нагрузку на SQL-сервер.
Конструкция В ИЕРАРХИИ крайне неэффективна внутри параметров виртуальной таблицы. Она заставляет СУБД выполнять вложенные подзапросы или строить огромные списки условий IN. Чтобы ускорить выполнение, мы рекомендуем заранее подготовить список всех элементов иерархии и поместить их во временную таблицу.
Разберем по шагам алгоритм оптимизации:
ВТ_ЭлементыГруппы.В ИЕРАРХИИ на обычное условие В, передавая массив ссылок, либо используем соединение с временной таблицей.Пример оптимизированного условия в параметрах виртуальной таблицы:
// Вместо: СубконтоДт1 В ИЕРАРХИИ (&Группа)
// Используем предварительно выгруженный массив:
И СубконтоДт1 В (&МассивСсылокЭлементов)
Часто программисты замечают, что добавление поля Регистратор в выборку замедляет запрос. Выясним причину: сама по себе ссылка на регистратор не должна тормозить выполнение Запрос.Выполнить(). Однако, если данные выводятся в отчет (особенно в СКД) или используется Регистратор.Представление, система начинает обращаться к таблицам всех типов документов, которые могут делать движения по регистру.
Важный совет: Если вам нужна только ссылка для возможности «провалиться» в документ из отчета, выбирайте только Регистратор. Избегайте конструкций Регистратор.Дата или Регистратор.Номер непосредственно в тяжелом запросе. Если эти данные необходимы, лучше получить их отдельным запросом к физическим таблицам документов после того, как основной объем данных уже отфильтрован.
Если ваш запрос содержит несколько блоков ОБЪЕДИНИТЬ ВСЕ, где каждый блок обращается к одной и той же виртуальной таблице с разными фильтрами, это создает избыточную нагрузку. Рассмотрим ситуацию: у вас есть общие фильтры (Организация, Период, Активность) и специфические (разные счета или субконто).
Проанализируем стратегию ускорения:
ВТ_ДанныеРегистра. Это позволит «отсечь» лишние записи один раз.ВТ_ДанныеРегистра, применяя к ней специфические условия в блоках объединения.Это позволит оптимизатору SQL-запросов работать с гораздо меньшим объемом данных на промежуточных этапах.
В некоторых случаях, когда требуется детализация до конкретной записи (периодичность Регистратор), виртуальная таблица ДвиженияССубконто может проигрывать в скорости обычным физическим таблицам. Посмотрим на структуру: физическая таблица РегистрБухгалтерии.Хозрасчетный уже содержит поля Субконто1, Субконто2 и т.д.
Если вам не требуется сложная логика получения остатков или развернутого сальдо, попробуйте написать запрос напрямую к основной таблице регистра с соединением к таблице субконто (_AccRgED) вручную. Это исключает «магию» платформы по сборке виртуальной таблицы и часто дает прирост производительности в 2–3 раза.
Для достижения максимальной скорости придерживайтесь следующих правил:
ВЫРАЗИТЬ для полей составного типа (Субконто, Регистратор).В ИЕРАРХИИ в параметрах виртуальных таблиц, заменяйте их на списки значений во временных таблицах.Представления ссылочных полей.