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