Почему резко замедлились запросы к регистрам бухгалтерии в 1С 8.3.16 и как это исправить?

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

Приветствуем вас, уважаемые коллеги! Сегодня мы детально разберем крайне неприятную техническую проблему, с которой массово сталкивались разработчики и администраторы систем «1С:Предприятие» при переходе на платформу версии 8.3.16. Речь идет о катастрофическом падении производительности (иногда в 30 раз и более!) при выполнении запросов к виртуальным таблицам регистров бухгалтерии.

Особенно ярко эта проблема проявляется после проведения процедуры реструктуризации таблиц информационной базы (например, через запуск утилиты «Тестирование и исправление», либо при банальном изменении метаданных регистра — включении индексации у какого-то измерения или реквизита). Давайте вместе проанализируем, почему так происходит на уровне СУБД, и рассмотрим практические пути решения этой проблемы.

Суть проблемы и классический медленный запрос

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


ВЫБРАТЬ
    ОсновнойОбороты.Период КАК Период,
    ОсновнойОбороты.СуммаОборот * &Множитель КАК Сумма
ИЗ
    РегистрБухгалтерии.Основной.Обороты(&НачалоПериода, &КонецПериода, День, , &ПорядокСубконто, Субконто1 В ИЕРАРХИИ (&Субконто1), , ) КАК ОсновнойОбороты

На платформе 8.3.15 этот запрос выполняется мгновенно. Однако стоит нам обновить платформу до версии 8.3.16 и выполнить реструктуризацию таблиц (даже обычное ТИИ с флагом «Реструктуризация таблиц информационной базы»), как этот же запрос начинает выполняться мучительно долго. Опытным путем пользователи выяснили, что если «откатить» реструктуризацию назад с помощью платформы 8.3.15.1747, скорость волшебным образом возвращается. Но вечно сидеть на старых релизах невозможно. Выясним истинные причины этой аномалии.

Глубокий технический анализ: что происходит под капотом СУБД?

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

1. Появление стандартного реквизита «УточнениеПериода» (PeriodAdjustment)

Начиная с версии 8.3.16, фирма «1С» внедрила в регистры бухгалтерии новый внутренний механизм поддержки так называемого «Уточнения периода». Даже если ваша конфигурация написана давно и вы не используете этот функционал, платформа принудительно перестраивает структуру таблиц СУБД при первой же реструктуризации на новом движке. В базу данных добавляется служебное поле PeriodAdjustment.

Это приводит к фундаментальному изменению логики транслятора запросов 1С в SQL. При обращении к виртуальным таблицам оборотов или остатков платформа начинает генерировать тяжелые условия, связывающие физические поля даты и это новое служебное поле. Оптимизатор СУБД (будь то MS SQL Server, PostgreSQL или встроенная файловая СУБД 1CD) из-за усложнения условий (часто содержащих конструкцию OR) «слепнет». Вместо того чтобы быстро прочитать данные из готовых таблиц итогов, СУБД переходит к полному сканированию физической таблицы движений (операция Full Table Scan), что на базах большого объема приводит к колоссальным задержкам.

2. Специфика файлового варианта баз данных (1CD)

В файловой версии базы данных встроенный движок СУБД от «1С» критично чувствителен к структуре индексов. При реструктуризации на платформе 8.3.15 индексы создаются по старому формату. Оптимизатор 8.3.16 умеет с ними работать в режиме обратной совместимости. Но как только реструктуризация запускается на платформе 8.3.16, индексы пересоздаются под новые алгоритмы параллельного расчета итогов. В сочетании с неоптимальным разбором запроса это полностью отключает использование индексов по субконто.

3. Опасность конструкции «В ИЕРАРХИИ» внутри параметров виртуальной таблицы

В нашем исходном запросе используется фильтр Субконто1 В ИЕРАРХИИ (&Субконто1) прямо в параметрах виртуальной таблицы оборотов. При работе транслятора запросов это условие разворачивается СУБД в сложный подзапрос, который пытается динамически сопоставить структуру подчинения справочника с итогами регистра. В версиях 8.3.16+ это окончательно разрушает план выполнения запроса.

---

Решение №1: Оптимизация запроса с помощью временных таблиц (Рекомендуемое решение)

Самый надежный и профессиональный способ решить проблему раз и навсегда (независимо от версии платформы и формата СУБД) — это отказаться от использования тяжелой конструкции В ИЕРАРХИИ непосредственно внутри параметров виртуальной таблицы.

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

Рассмотрим детально оптимизированный код запроса:


// Шаг 1: Собираем всю иерархию элементов справочника во временную таблицу
ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка
ПОМЕСТИТЬ ВТ_РазвернутоеСубконто
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Номенклатура.Ссылка В ИЕРАРХИИ(&Субконто1)

ИНДЕКСИРОВАТЬ ПО
    Ссылка
;

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

Почему это работает быстрее? СУБД получает на вход конкретный, заранее подготовленный и проиндексированный список значений идентификаторов (ссылок). Вместо того чтобы вычислять иерархические связи «на лету» во время расчета бухгалтерских итогов, база данных делает легкую выборку по индексу. Время выполнения запроса сокращается до миллисекунд.

Решение №2: Обновление платформы на исправленные релизы

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

Фирма «1С» признала проблему неоптимальной генерации планов запросов при работе с полями PeriodAdjustment. В последующих ветках платформы (начиная с релизов 8.3.18 и выше, а особенно в стабильных сборках 8.3.20, 8.3.21 и далее) были внесены серьезные патчи в SQL-транслятор. Оптимизатор научился корректно строить планы запросов к итогам регистров бухгалтерии даже при наличии новых служебных полей. Если у вас есть возможность — обновите платформу до актуального стабильного релиза.

Решение №3: Временный административный обход (Костыль)

Если вы жестко привязаны к релизам линейки 8.3.16 и вам нужно срочно вернуть работоспособность базы «прямо сейчас», можно применить метод, обнаруженный автором форума:

  1. Установите на технологическом сервере или локальной машине администратора старую версию платформы 8.3.15.1747.
  2. Запустите конфигуратор базы данных через эту старую версию платформы.
  3. Откройте меню Администрирование — Тестирование и исправление.
  4. Выберите пункт «Реструктуризация таблиц информационной базы» и запустите процесс выполнения.
  5. После завершения реструктуризации верните пользователей на рабочую платформу 8.3.16. Все запросы снова будут работать быстро.

Важное предупреждение: Помните, что данный метод является временной полумерой. Любое последующее изменение метаданных регистра бухгалтерии (например, добавление реквизита при обновлении конфигурации) на платформе 8.3.16 снова автоматически запустит реструктуризацию в новом формате, и производительность опять упадет.

Подведем итоги

Мы проанализировали серьезную проблему падения производительности регистров бухгалтерии в платформе 1С 8.3.16. Главный вывод, который мы можем сделать: всегда разделяйте тяжелые иерархические выборки и запросы к виртуальным таблицам. Вынос условий В ИЕРАРХИИ во временные таблицы с обязательным индексированием — это золотой стандарт разработки в 1С, который защитит ваши базы данных от любых неожиданных изменений в платформенных механизмах оптимизации запросов СУБД.

← На главную