Для чего нужны индексы в Таблице Значений 1С и как их правильно использовать?

Программист IT и автоматизация бизнеса
← На главную

При работе с объектом ТаблицаЗначений в 1С мы привычно оперируем его колонками и строками. Однако свойство Индексы часто остается в тени, вызывая вопросы о его предназначении. Давайте вместе разберемся, зачем нужны индексы, в каких случаях их использование оправдано, а когда может навредить, и как они влияют на производительность кода.

Основное назначение индексов: ускорение поиска

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

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

Таким образом, главная и, по сути, единственная задача индексов — радикальное ускорение поиска строк с помощью методов Найти() и НайтиСтроки().


// Создание таблицы и добавление колонки
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура");
ТЗ.Колонки.Добавить("Количество");

// ... код заполнения таблицы тысячами строк ...

// Создание индекса по колонке "Номенклатура"
ТЗ.Индексы.Добавить("Номенклатура");

// Теперь поиск по этой колонке будет работать очень быстро
НайденнаяСтрока = ТЗ.Найти("Товар123", "Номенклатура");

Когда создание индексов действительно оправдано?

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

  1. Большой объем таблицы. Заметный прирост производительности от индекса вы увидите на таблицах, содержащих несколько тысяч строк и более. Для таблиц на 100-500 строк затраты на создание и поддержку индекса могут свести на нет всю выгоду, а полный перебор строк и так будет достаточно быстрым.
  2. Частые операции поиска. Если вам нужно найти одну строку в таблице один раз, создавать индекс бессмысленно. Индексы раскрывают свой потенциал, когда поиск выполняется многократно, например, внутри цикла при сопоставлении данных из двух больших таблиц.
  3. Высокая селективность колонки. Селективность — это степень уникальности данных. Индекс наиболее эффективен, когда в колонке много различных значений (например, уникальные коды товаров, номера документов, GUIDы). И наоборот, если в колонке всего 2-3 варианта (например, "Пол" со значениями "Мужской"/"Женский" или булево поле "Проведен"), польза от индекса будет минимальной, а иногда он может даже замедлить работу.

Особенности работы с методами Найти() и НайтиСтроки()

Важно понимать, как именно методы поиска взаимодействуют с индексами, особенно когда поиск нужно выполнить по нескольким колонкам. Здесь есть ключевое различие.

Метод Найти()

Этот метод предназначен для поиска первой попавшейся строки, удовлетворяющей условию. Он может использовать индекс, но только по одной колонке. Даже если вы передадите в него для поиска структуру с несколькими полями, или создадите составной индекс, Найти() проигнорирует его и будет выполнять полный перебор. Индекс будет задействован только если вы ищете по одной колонке, по которой ранее был создан простой индекс.


// Индекс будет использован
ИндексПоСотруднику = ТЗ.Индексы.Добавить("Сотрудник");
НайденнаяСтрока = ТЗ.Найти("Иванов", "Сотрудник");

// Индекс НЕ будет использован, будет полный перебор
Отбор = Новый Структура;
Отбор.Вставить("Сотрудник", "Иванов");
Отбор.Вставить("Отдел", "Отдел продаж");
НайденнаяСтрока = ТЗ.Найти(Отбор);

Метод НайтиСтроки()

Этот метод возвращает массив всех строк, удовлетворяющих отбору. Его главное преимущество в том, что он умеет эффективно работать с составными индексами — индексами, построенными сразу по нескольким колонкам.

Чтобы НайтиСтроки() задействовал индекс, нужно выполнить два условия:

  1. Создать составной индекс, перечислив имена колонок через запятую.
  2. Передать в метод структуру отбора, в которой ключи (имена полей) точно соответствуют колонкам, входящим в составной индекс. Порядок колонок в структуре отбора при этом значения не имеет.

Посмотрим на пример:


// Создаем таблицу
ТаблицаДокументов = Новый ТаблицаЗначений;
ТаблицаДокументов.Колонки.Добавить("Контрагент");
ТаблицаДокументов.Колонки.Добавить("Договор");
ТаблицаДокументов.Колонки.Добавить("Сумма");

// ... заполняем таблицу ...

// Создаем составной индекс по двум колонкам
ТаблицаДокументов.Индексы.Добавить("Контрагент, Договор");

// Готовим структуру для поиска
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Договор", НужныйДоговор); // Порядок не важен
СтруктураОтбора.Вставить("Контрагент", НужныйКонтрагент);

// Выполняем поиск. Он будет очень быстрым, т.к. используется составной индекс.
НайденныеСтроки = ТаблицаДокументов.НайтиСтроки(СтруктураОтбора);

Если бы мы искали только по полю "Контрагент", то составной индекс "Контрагент, Договор" не был бы использован. Для этого потребовался бы отдельный простой индекс по колонке "Контрагент".

Цена использования индексов: о чем нужно помнить

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

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

← На главную