Почему запрос к оборотному регистру накопления медленно работает, если условие задано по первому измерению без использования периода?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← К списку

Мы сталкиваемся с ситуацией, когда, казалось бы, простой запрос к оборотному регистру накопления выполняется крайне медленно, несмотря на наличие индекса по первому измерению. Давайте разберем эту проблему на примере типового механизма в 1С:Управление торговлей 11.5 и выясним, почему так происходит, а также предложим эффективные решения. Представим типовой сценарий: мы вводим документ "Реализация товаров и услуг" на основании "Заказа клиента". Внутри процедуры Документы.РеализацияТоваровУслуг.ЗаполнитьПоОстаткамЗаказов() вызывается процедура ПолучитьРезультатЗапросаПоОстаткамЗаказов(). Вся логика сводится к следующему запросу:


ВЫБРАТЬ
    РаспоряженияОбороты.Распоряжение КАК ЗаказКлиента,
    РаспоряженияОбороты.Номенклатура КАК Номенклатура,
    РаспоряженияОбороты.Характеристика КАК Характеристика,
    РаспоряженияОбороты.КодСтроки КАК КодСтроки,
    РаспоряженияОбороты.Склад КАК Склад,
    РаспоряженияОбороты.Серия КАК Серия,
    РаспоряженияОбороты.КОформлениюОборот КАК КОформлению,
    РаспоряженияОбороты.СуммаОборот КАК Сумма
ИЗ
    РегистрНакопления.РаспоряженияНаОтгрузку.Обороты(, , , Распоряжение =&Заказ) КАК РаспоряженияОбороты

Мы видим, что этот запрос фильтруется по измерению Распоряжение, которое является первым измерением в регистре и, предположительно, должно быть проиндексировано. Однако на практике он может читать миллионы строк данных, что вызывает серьезные проблемы с производительностью. Возникает закономерный вопрос: почему так происходит и есть ли в этом скрытый смысл?

Выясняем причину неэффективной работы запроса

Давайте проанализируем ситуацию и выясним причину такого поведения. Обратимся к документации 1С и общим принципам работы с индексами оборотных регистров накопления: 1. Кластерный индекс и поле "Период": Для виртуальной таблицы оборотов (РегистрНакопления.ИмяРегистра.Обороты) кластерный индекс в большинстве случаев начинается с поля Период. Это означает, что логическая структура индекса может выглядеть так: Период + Измерение1 + Измерение2 + .... 2. Условие по "Периоду": Если в запросе к таблице оборотов не задано условие по Периоду (как в нашем примере), или оно задано неэффективно (например, только Период > или Период <), то платформа может не использовать этот кластерный индекс полностью. В такой ситуации система вынуждена выполнять полное сканирование (Seq Scan) всей таблицы оборотов, что и приводит к чтению огромного количества строк и низкой производительности. 3. Порядок измерений: Порядок следования измерений в регистре имеет критическое значение для производительности. Кластерный индекс, как правило, включает измерения в той последовательности, в которой они указаны. Если измерение, по которому мы фильтруем, находится не на первой позиции после Периода, или если само Период не участвует в условиях отбора, эффективность индексации снижается. 4. Наш пример: В запросе РегистрНакопления.РаспоряженияНаОтгрузку.Обороты(, , , Распоряжение =&Заказ) мы видим, что условия по Периоду отсутствуют. Это и является основной причиной того, что индекс по Распоряжение не задействуется эффективно, и запрос вынужден обрабатывать весь объем данных регистра. Таким образом, "скрытый смысл" заключается в специфике построения индексов для оборотных регистров и важности включения поля Период в условия запроса.

Решение 1: Оптимизация порядка измерений в регистре

Одним из наиболее эффективных способов решения данной проблемы является правильное расположение измерений в регистре. Автор исходной темы обнаружил, что, передвинув измерение Распоряжение на вторую позицию в регистре, он добился использования индекса и снижения количества читаемых строк до 12. Рассмотрим подробнее этот подход:

  1. Анализ частоты отборов: В первую очередь, проанализируйте, по каким измерениям вы чаще всего производите отборы в запросах к оборотному регистру.
  2. Перемещение селективных измерений: Рекомендуется ставить первыми наиболее селективные измерения, по которым чаще всего будут выполняться отборы. Если Период всегда является частью кластерного индекса, то следующее за ним измерение, по которому вы часто фильтруете, будет иметь наилучший эффект.
  3. Подтверждение от разработчиков: Важно отметить, что разработчики 1С также осознают эту проблему. В некоторых версиях конфигураций (например, УТ 11.5.24, КА 2.5.24) они внесли исправления, передвинув подобные измерения на вторые позиции (или добавив новое первое измерение, сделав текущее вторым), что подтверждает эффективность данного подхода.
  4. Индексирование измерений: Для таблицы оборотов индексирование измерений, начиная со второго, может быть полезным. Убедитесь, что необходимые измерения проиндексированы в свойствах регистра.

Как мы можем это сделать?

  1. Откройте конфигуратор 1С.
  2. Перейдите к нужному Регистру Накопления (в нашем случае, РаспоряженияНаОтгрузку).
  3. На вкладке "Данные" найдите список измерений.
  4. Измените порядок измерений таким образом, чтобы измерение, по которому вы часто фильтруете (например, Распоряжение), находилось на наиболее оптимальной позиции (часто это вторая позиция после "виртуального" Периода).
  5. Обновите конфигурацию базы данных.

Важный момент: Мы должны помнить, что изменение порядка измерений в уже используемом регистре с большим объемом данных может быть длительной операцией, так как потребуется перестроение таблиц в базе данных. Планируйте такую операцию в нерабочее время.

Решение 2: Применение механизма агрегатов для повышения производительности

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

Что такое агрегаты?

Агрегаты – это специальные физические таблицы в базе данных, которые хранят предварительно рассчитанные (свернутые) итоговые данные (обороты) для определенного набора измерений и с заданной периодичностью. Платформа 1С может использовать эти агрегаты для выполнения запросов, что значительно ускоряет получение итоговых данных, избегая полного сканирования основной таблицы оборотов.

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

Мы рекомендуем использовать агрегаты в следующих случаях:

  1. Большие объемы данных: Регистры содержат сотни тысяч и миллионы записей.
  2. Частые аналитические отчеты: Требуется часто формировать отчеты по различным аналитическим разрезам, где скорость критична.
  3. Ограничение количества измерений: Регистр имеет разумное количество измерений (обычно не более 30), чтобы агрегаты были управляемыми.

Пошаговая настройка и использование агрегатов

Давайте рассмотрим по шагам, как настроить и использовать агрегаты:

  1. Откройте конфигуратор 1С.
  2. Перейдите к нужному регистру накопления: В дереве объектов конфигурации найдите интересующий нас Регистр Накопления.
  3. Настройте агрегаты:
    • Перейдите на вкладку "Прочее" или "Дополнительно" (в зависимости от версии платформы) в свойствах регистра.
    • Найдите раздел "Агрегаты" и добавьте новый агрегат.
    • Для каждого агрегата укажите набор измерений и периодичность (например, День, Неделя, Месяц), по которым будут храниться сводные данные. Мы должны продумать, какие комбинации измерений и периодичности чаще всего используются в наших запросах.
  4. Обновите конфигурацию базы данных.
  5. Включите режим использования агрегатов: После обновления конфигурации, в режиме 1С:Предприятие необходимо включить использование агрегатов. Это обычно делается через функциональность платформы или в параметрах информационной базы.
  6. Выполните перестроение агрегатов: Агрегаты не заполняются автоматически. После их создания или изменения конфигурации, а также при больших объемах данных, необходимо выполнить их перестроение. Этот процесс может занять значительное время.

Важные моменты при работе с агрегатами

Дополнительные рекомендации и анализ ситуации

Продолжим наше совместное исследование и рассмотрим дополнительные аспекты, которые помогут нам глубже понять проблему и найти оптимальные решения.

  1. Ограничения условий сравнения (> и <): Мы выяснили, что условия сравнения (например, Период > &НачалоПериода) на первом поле индекса могут затруднять использование последующих полей индекса. Если нам необходим запрос к оборотам за период, всегда старайтесь указывать как начало, так и конец периода (Период МЕЖДУ &Начало И &Конец) для максимально эффективного использования индекса по Периоду.
  2. Таблица оборотов vs Таблица движений: Оборотный регистр хранит данные в двух основных таблицах: таблице движений (сырые данные, записываемые документами) и таблице оборотов (агрегированные данные). Виртуальная таблица оборотов может использовать данные обеих таблиц. Идеальный случай — когда запрос может быть выполнен исключительно к таблице оборотов, так как это самый быстрый способ получения итоговых данных.
  3. Использование регистра остатков: Если нам необходимо часто контролировать текущие остатки, особенно в нагруженных системах, мы рекомендуем использовать регистр вида "Остатки", а не оборотный регистр. Регистр остатков изначально оптимизирован для получения актуальных остатков.
  4. Обновления конфигураций: Как мы уже упоминали, разработчики 1С постоянно работают над оптимизацией. Обновления конфигураций (например, переход на версии 2.5.24 в УТ/КА/ERP) часто включают исправления, связанные с порядком измерений в регистрах и другими механизмами для повышения производительности. Всегда следите за актуальными версиями и читайте описания изменений.
  5. Анализ плана запроса: Для глубокого анализа производительности мы всегда рекомендуем использовать средства платформы для просмотра и анализа плана запроса. Это позволит нам точно увидеть, какие индексы используются (или не используются), какие таблицы сканируются и где возникают "узкие места".

Вместе мы разобрали сложную, но часто встречающуюся проблему неэффективной работы запросов к оборотным регистрам накопления. Мы выяснили, что понимание структуры индексации и правильный порядок измерений, а также использование агрегатов, являются ключевыми факторами для достижения высокой производительности. Применяя эти знания, мы сможем значительно оптимизировать работу наших информационных систем на платформе 1С.

← К списку