Как ускорить тяжелый запрос к регистру бухгалтерии при сверке данных?

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

При сверке данных между двумя информационными базами нередко приходится сопоставлять документы по дополнительным реквизитам или свойствам. Однако сложные запросы к виртуальным таблицам регистров бухгалтерии с множеством соединений могут выполняться крайне медленно — вплоть до нескольких часов. Разберем основные причины падения производительности и выясним, как правильно переписать такой запрос для многократного ускорения.

Анализ причин медленной работы запроса

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

  1. Неявные соединения при обращении через точку к составным типам (разыменование ссылок): конструкция вида ТиповойОбороты.Регистратор.Дата или Сторнирование.ДокументОснование.Дата заставляет платформу 1С формировать в СУБД левые соединения со всеми таблицами документов, входящими в составной тип Регистратор или ДокументОснование. Если в типе десятки документов, план запроса превращается в громоздкое дерево соединений.
  2. Разыменование полей субконто: обращение к реквизитам субконто без явного ограничения типа (например, ОборотыВсе.Субконто1.Наименование, ОборотыВсе.Субконто2.ajs_id) порождает соединения со всеми типами объектов, включенными в план видов характеристик ВидыСубконтоХозрасчетные.
  3. Сравнение поля составного типа в условии: реквизит Значение регистра сведений ЗначенияСвойствОбъектов имеет составной тип. Использование его в выражении МЕЖДУ &Дата1 И &Дата2 или внутри функции ЕСТЬNULL без приведения типа приводит к неявному преобразованию типов на стороне СУБД, что исключает использование индексов и вызывает полное сканирование таблицы (Index Scan / Table Scan).
  4. Отсутствие конечной даты в параметрах виртуальной таблицы: если опустить второй параметр в виртуальной таблице РегистрБухгалтерии.Типовой.Обороты(&Дата1, , ...), платформа считывает все записи с начальной даты до бесконечности, а затем фильтрует их во внешнем блоке ГДЕ.
  5. Фильтрация по датам за пределами параметров виртуальной таблицы: наложение условий на дату документа в блоке ГДЕ лишает виртуальную таблицу возможности применить штатные кластерные индексы по периоду и счету.

Способ 1. Приведение составных типов с помощью ВЫРАЗИТЬ

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

Посмотрим на пример приведения типа для регистратора и документа-основания:


ВЫБРАТЬ
    ВЫРАЗИТЬ(ТиповойОбороты.Регистратор КАК Документ.Сторнирование).ДокументОснование КАК ДокументОснование
ИЗ
    РегистрБухгалтерии.Типовой.Обороты(&Дата1, &Дата2, Регистратор, Счет = &Счет, , Организация = &Организация, , ) КАК ТиповойОбороты

Аналогично поступим с полями субконто при получении их реквизитов. Если Субконто1 гарантированно является справочником контрагентов, приведем его к нужному типу:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Обороты.Субконто1 КАК Справочник.Контрагенты).Наименование КАК КонтрагентНаименование,
    ВЫРАЗИТЬ(Обороты.Субконто1 КАК Справочник.Контрагенты).ИдентификационныйКодЛичности КАК БИН,
    ВЫРАЗИТЬ(Обороты.Субконто2 КАК Справочник.ДоговорыКонтрагентов).ajs_id КАК ajs_id
ИЗ
    Обороты КАК Обороты

Для поля Значение регистра сведений ЗначенияСвойствОбъектов также обязательно задаем тип:

ВЫРАЗИТЬ(ЗначенияСвойствОбъектовДатаББ.Значение КАК ДАТА)

Способ 2. Использование стандартного поля Период вместо Регистратор.Дата

В большинстве конфигураций 1С проводки и движения документов формируются на дату самого документа. В виртуальной таблице оборотов с периодичностью Регистратор доступно стандартное поле Период.

Замена конструкции ТиповойОбороты.Регистратор.Дата на ТиповойОбороты.Период позволяет получить дату движения без разыменования ссылки и без дополнительных соединений к таблицам документов.

Способ 3. Подготовка дат во временной таблице с индексацией

Разберем по шагам наиболее эффективный архитектурный подход. Вместо объединения тяжелых таблиц в одном запросе разобьем задачу на этапы с использованием временных таблиц.

  1. Шаг 1: формируем временную таблицу документов, попадающих в требуемый диапазон дат с учетом дополнительных свойств и документов сторнирования.
  2. Шаг 2: индексируем временную таблицу по полю ссылки на документ.
  3. Шаг 3: соединяем подготовленный список документов с таблицей движений или оборотов регистра бухгалтерии.

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


// 1. Собираем документы с учетом даты свойства
ВЫБРАТЬ
    Свойства.Объект КАК Ссылка,
    ВЫРАЗИТЬ(Свойства.Значение КАК ДАТА) КАК РеальнаяДата
ПОМЕСТИТЬ ВТ_ДатыСвойств
ИЗ
    РегистрСведений.ЗначенияСвойствОбъектов КАК Свойства
ГДЕ
    Свойства.Свойство = &СвойствоДатаББ
    И ВЫРАЗИТЬ(Свойства.Значение КАК ДАТА) МЕЖДУ &Дата1 И &Дата2
ИНДЕКСИРОВАТЬ ПО
    Ссылка
;

// 2. Получаем обороты и связываем их с подготовленными данными
ВЫБРАТЬ
    Движения.Счет КАК Счет,
    Движения.Организация КАК Организация,
    Движения.Субконто1 КАК Субконто1,
    Движения.Субконто2 КАК Субконто2,
    Движения.Сумма КАК Сумма
ПОМЕСТИТЬ ВТ_Обороты
ИЗ
    РегистрБухгалтерии.Типовой.ДвиженияССубконто(&Дата1, &Дата2, Счет = &Счет И Организация = &Организация) КАК Движения
ГДЕ
    Движения.Регистратор В (ВЫБРАТЬ ВТ_ДатыСвойств.Ссылка ИЗ ВТ_ДатыСвойств)
;

// 3. Выбираем и группируем итоговые данные с явным приведением типов
ВЫБРАТЬ
    ВЫРАЗИТЬ(ВТ_Обороты.Субконто1 КАК Справочник.Контрагенты).Наименование КАК Контрагент,
    ВЫРАЗИТЬ(ВТ_Обороты.Субконто2 КАК Справочник.ДоговорыКонтрагентов).Наименование КАК Договор,
    СУММА(ВТ_Обороты.Сумма) КАК Сумма
ИЗ
    ВТ_Обороты КАК ВТ_Обороты
СГРУППИРОВАТЬ ПО
    ВЫРАЗИТЬ(ВТ_Обороты.Субконто1 КАК Справочник.Контрагенты).Наименование,
    ВЫРАЗИТЬ(ВТ_Обороты.Субконто2 КАК Справочник.ДоговорыКонтрагентов).Наименование

Способ 4. Переход на физическую таблицу движений

Виртуальная таблица Обороты с периодичностью Регистратор фактически выполняет группировку записей регистра бухгалтерии. Если требуется детализация до каждого регистратора и субконто, эффективнее обращаться напрямую к физической таблице РегистрБухгалтерии.Типовой.ДвиженияССубконто (или основной таблице регистра бухгалтерии), фильтруя записи по счету, периоду и организации.

Важные правила при оптимизации запросов к регистрам:

  1. Всегда передавайте оба параметра периода (НачалоПериода и КонецПериода) в виртуальные таблицы.
  2. Используйте ИНДЕКСИРОВАТЬ ПО для полей временных таблиц, которые участвуют в соединениях и условиях В / ГДЕ.
  3. Никогда не обращайтесь через точку к реквизитам полей составного типа без предварительного вызова ВЫРАЗИТЬ.
  4. Ограничивайте типы субконто при выборке их реквизитов.
← На главную