Как платформа 1С создает индексы при проектировании регистров сведений

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

При проектировании высоконагруженных систем на платформе 1С:Предприятие одним из ключевых факторов производительности является правильная работа с индексами СУБД. Регистры сведений — это один из наиболее часто используемых прикладных объектов для хранения нетехнологических данных (цены, курсы валют, настройки, штрихкоды и т.д.). Понимание того, как именно платформа транслирует наши метаданные в физические индексы на уровне базы данных (MS SQL Server, PostgreSQL, IBM DB2 или Oracle), позволяет избежать критических проблем с производительностью и блокировками. Рассмотрим подробно этот механизм.

Базовые правила индексации непериодических регистров сведений

Когда мы создаем новый непериодический регистр сведений с независимым режимом записи, платформа автоматически создает первичный ключ на уровне СУБД. Этому ключу соответствует уникальный кластерный индекс. Давайте разберем, по какому принципу он строится.

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

Организация + Номенклатура + Склад

Этот индекс является уникальным. СУБД на физическом уровне гарантирует, что в таблице не может существовать двух записей с одинаковым набором этих измерений.

Теперь проанализируем, как влияют различные флаги в свойствах измерений на создание дополнительных (некластерных) индексов:

  1. Свойство "Ведущее" (Leading): Если у измерения включено это свойство, платформа создает дополнительный некластерный уникальный индекс. Этот индекс строится по схеме: ВедущееИзмерение + ОстальныеИзмерения.... Наличие такого индекса позволяет платформе мгновенно находить и очищать движения при удалении элементов ведущего объекта (например, при удалении номенклатуры удаляются связанные записи в регистре).
  2. Свойство "Основной отбор" (Main Filter): Если для измерения установлен этот признак, система автоматически генерирует дополнительный некластерный неуникальный индекс. Он строится по схеме: ИзмерениеСОтбором + ОстальныеИзмерения.... Это критически важно для быстрого выполнения запросов, где данное измерение выступает в качестве единственного или первого условия фильтрации.
  3. Свойство "Индексировать" (Index): Доступно в том случае, если свойство "Ведущее" выключено. При выборе значения "Индексировать" или "Индексировать с дополнительным упорядочиванием" платформа создает некластерный неуникальный индекс по этому полю, помогая оптимизировать запросы с отборами по данному измерению.

Влияние периодичности регистра на структуру кластерного индекса

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

Если регистр сведений становится периодическим (например, в пределах секунды, дня или месяца), платформа кардинально перестраивает структуру основного кластерного индекса:

Такой подход обеспечивает максимальную скорость работы с временными интервалами и получение актуальных срезов данных. Однако здесь кроется серьезная ловушка для разработчика: если вы выполняете запрос с отбором по Измерению1, но не указываете условие по времени (Период), СУБД не сможет эффективно использовать данный кластерный индекс. Произойдет сканирование индекса (Index Scan) вместо быстрого поиска (Index Seek), что приведет к падению производительности на больших таблицах. В таких случаях обязательно нужно настраивать дополнительное индексирование для измерений.

Почему порядок следования измерений имеет решающее значение

Давайте разберем фундаментальное правило работы составных индексов в реляционных базах данных — правило левого префикса. Индекс по полям А + Б + В эффективно работает только тогда, когда в условиях запроса («ГДЕ» или в параметрах виртуальной таблицы) используются:

Если мы пишем запрос, в котором отбор идет только по полю Б или по связке Б + В, СУБД проигнорирует этот индекс (либо его эффективность будет крайне низкой).

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

  1. Контрагент
  2. Договор

Кластерный индекс выглядит как: Период + Контрагент + Договор.

Если мы часто выполняем запросы с поиском по конкретному договору без указания контрагента, система будет "тормозить". Чтобы решить эту проблему, нам необходимо либо поменять измерения местами в дереве метаданных (если это логично для бизнес-архитектуры), либо установить для измерения Договор свойство "Индексировать", чтобы платформа создала под него отдельный физический некластерный индекс.

Особенности индексации регистров сведений, подчиненных регистратору

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

Платформа 1С отказывается от стандартного кластерного индекса по измерениям и строит его по совершенно иному принципу:

Это технологически необходимо платформе для того, чтобы при перепроведении или отмене проведения документа СУБД могла моментально найти, заблокировать и удалить все движения, относящиеся к данному конкретному Регистратору.

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

Механизм среза последних и среза первых

Разберем, как платформа работает с виртуальными таблицами СрезПоследних и СрезПервых. Начинающие разработчики часто думают, что для этих таблиц СУБД создает какие-то отдельные скрытые индексы. Это не так.

При обращении к срезам данных платформа генерирует сложный SQL-запрос с подзапросами, который полностью опирается на существующую структуру метаданных. В СУБД этот запрос задействует основной кластерный индекс регистра.

Рассмотрим типичный пример запроса получения среза последних цен:


ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, Номенклатура = &Номенклатура) КАК ЦеныНоменклатурыСрезПоследних

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

Скрытые индексы при использовании Планов обмена

Если наш регистр сведений включен в состав хотя бы одного Плана обмена и для него активирована авторегистрация изменений, платформа создает в базе данных дополнительную служебную таблицу регистрации изменений. На уровне СУБД она обычно имеет префикс _InfoRgChngX (где X — уникальный идентификатор таблицы).

Для этой таблицы платформа автоматически создает свои собственные индексы:

Необходимо учитывать, что при любой записи в регистр сведений платформа будет выполнять сопутствующую запись и обновление индексов в этой служебной таблице. Это может существенно снизить общую скорость записи данных (нагрузка на операции дискового ввода-вывода), поэтому включать регистры в планы обмена следует обдуманно.

Рекомендации по индексации ресурсов и реквизитов

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

Для реквизитов регистра свойство "Индексировать" может быть очень полезно, если данный реквизит часто используется в условиях запросов (в секции ГДЕ). Например, если у нас есть реквизит АвторИзменения и нам периодически нужно быстро выбирать записи, измененные конкретным пользователем.

Что касается ресурсов — их индексация в 95% случаев является архитектурной ошибкой. Ресурсы предназначены исключительно для хранения целевых значений (сумм, цен, количеств, текстовых описаний). Если вам регулярно приходится накладывать жесткие условия фильтрации на значения ресурса в запросах, это явный сигнал о том, что данное поле спроектировано неверно и должно быть переведено в разряд измерений регистра.

Резюмирующая таблица физических индексов регистра сведений в СУБД

Для закрепления материала сведем все возможные варианты генерации индексов платформой 1С в удобную структуру:

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

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

← На главную