Влияние ограничений длины ключа индексов на проектирование объектов метаданных

В процессе работы с 1С:Предприятием 8 в некоторых случаях может выдаваться сообщение: «Длина ключа индекса превышает максимально допустимую» или другое аналогичного содержания. Этот документ посвящен причинам возникновения такого рода ошибок и содержит рекомендации по их предотвращению.

Индексы

Для ускорения поиска нужных записей в таблицах базы данных создаются индексы. 1С:Предприятие 8.1 создает индексы автоматически в соответствии с набором объектов метаданных конфигурации и их свойствами. Подробная информация об индексах, создаваемых 1С:Предприятием в таблицах базы данных, непосредственно доступных в запросах, содержится в документе «Индексы таблиц базы данных».

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


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

Период + Счет + Измерение1 [+ Измерение2 …] + ЗначениеСубконто1 [+ ЗначениеСубконто2 + …]

Ограничения на индексы

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

Файловый вариант информационной базы

Единственным ограничением на использование индекса при использовании СУБД, встроенной в 1С:Предприятие, является максимально допустимая суммарная длина ключа в индексе, равная 1920 байт. При попытке создания индекса с длиной ключа, превышающей 1920 байт, будет выдано сообщение об ошибке.

Клиент-серверный вариант информационной базы

Клиент-серверный вариант информационной базы подразумевает использование Microsoft SQL Server в качестве СУБД. В Microsoft SQL Server определены следующие ограничения на использование индексов:

  • максимальное количество полей, участвующих в индексе, равно 16.
  • максимально допустимая суммарная длина ключа в индексе равна 900 байт.


Важно иметь в виду, что в процессе определения объектов метаданных 1С:Предприятие при попытке создания индекса, включающего более 16 полей, в клиент-серверном варианте ИБ индекс усекается справа до 16. Это повышает надежность работы системы, но может привести к некоторому снижению производительности операций над соответствующими таблицами из-за ухудшения качества усеченных индексов.

О вычислении длины ключа

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

  • Во-первых, способ построения индекса существенно зависит от используемой СУБД.
  • Во-вторых, длина ключа каждой записи индекса может зависеть от содержащихся в ней данных. В частности, при использовании в индексе полей типа VARBINARY Microsoft SQL Server помещает в запись индекса данные фактической длины, которая может быть меньше, чем заданная максимальная длина поля. С другой стороны, при использовании в индексе данных типа NCHAR или NVARCHAR длина представления этих данных в записи индекса для некоторых СУБД может существенно превышать максимальное количество символов, отведенное на поле строкового типа, из-за использования ключей сравнения (Collation Key), построение которых зависит от национальных настроек базы данных.


По этим причинам 1С:Преприятие 8.1 не выполняет автоматической проверки длин ключей создаваемых индексов. Таким образом, если при создании или использовании индекса будет превышена максимальная для данной СУБД длина ключа, то 1С:Предприятие выдаст сообщение об ошибке, порожденное используемой СУБД.

Рекомендации по конфигурированию

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

  • Не используйте индексирование по строковым полям, суммарная длина которых превышает 300 символов. Такой индекс может быть создан при выборе в значения «Индексирование» или «Индексировать с дополнительным упорядочиванием» свойства «Индексировать» реквизита или измерения. Кроме того, индекс по полю будет создан при вхождении этого поля в какой-нибудь критерий отбора.
  • Не используйте в регистрах слишком много измерений, особенно, если среди них есть поля строковых типов. Для ориентировки можно считать, что поле типа число занимает 16 байт ключа индекса, строка — 3*n байт (где n — максимальная длина строки), дата — 8 байт, булево — 1 байт, ссылка на один объект — 16 байт, ссылка на несколько объектов — 20 байт.
  • Избегайте использование измерений составных типов. Исключение может составлять комбинирование ссылок различных типов.
  • Не задавайте в планах счетов слишком большое максимальное количество субконто (превышение числа 5 может быть оправдано только в случае более тщательного анализа опасности превышения максимальной длины ключа индекса, и эффективности работы самого регистра).
  • Не рекомендуется в одном регистре бухгалтерии использовать субконто со значениями различных примитивных типов. См. также Назначение прикладного объекта «План видов характеристик».
  • Не используйте в регистрах бухгалтерии слишком большое количество измерений в сочетании с большим максимальным количеством субконто.

 

Техническая часть:

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

  • Число: (Длина + 1) / 2 + (Длина + 1) % 2
  • Строка: Длина * 3 + 2
  • Дата: 8
  • Булево: 1
  • Ссылка: 16


Кроме этого, существует ограничение на количество полей, входящих в составной индекс. Для СУБД, отличных от файловой, максимальное количество полей в составном индексе – 16. Для файловой СУБД – 256. Если индекс содержит большее количество полей – они автоматически отбрасываются. Так работает модель информационной базы 1С:Предприятия.

Теперь об индексировании:

Рассмотрим самый простой случай непериодического независимого регистра сведений с тремя измерениями: Изм1, Изм2, Изм3.
Для него система всегда автоматически (независимо от того, указаны или нет свойства Индексировать для каждого измерения) строит основной индекс Изм1 + Изм2 + Изм3, в который входят все измерения в том порядке, в котором они заданы при конфигурировании.
Если для Изм2, например, задается свойство Индексировать, то создается еще один дополнительный индекс: Изм2 + Изм1 + Изм3.
Если для Изм3, например, задается свойство Индексировать, то создается еще один дополнительный индекс: Изм3 + Изм1 + Изм2.

Таким образом, в вашем случае, для регистра создано 20 индексов: основной и 19 дополнительных. Каждый из индексов содержит 20 полей.

Подробнее обо всех основных и дополнительных индексах написано на ИТС:
1С:Предприятие. Работаем с программами  
  1C. Методическая поддержка 1С:Предприятия 8.1
     Администрирование
       Индексы таблиц базы данных

Судя по вашему сообщению, все измерения строкового типа, значит, на каждое измерение может максимально приходиться 1920/20 = 96 байт.
Исходя из приведенной выше формулы можно заключить, что длина каждого строкового измерения не может быть больше (96-2)/3 = 31 символа.


Таким образом, в порядке возрастания полезности, можно посоветовать следующее:
— снять свойство Индексировать у всех измерений, это удалит 19 ненужных индексов. 
— проанализировать длину измерений и уменьшить ее исходя из максимум 31 символа на одно измерение.
— перепроектировать регистр.

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