При работе с объектом ТаблицаЗначений в 1С мы привычно оперируем его колонками и строками. Однако свойство Индексы часто остается в тени, вызывая вопросы о его предназначении. Давайте вместе разберемся, зачем нужны индексы, в каких случаях их использование оправдано, а когда может навредить, и как они влияют на производительность кода.
Представьте, что вы ищете нужный термин в огромной энциклопедии без алфавитного указателя. Вам пришлось бы последовательно пролистать каждую страницу. Это и есть поиск в ТаблицеЗначений без индекса — полный перебор всех строк, пока не найдется совпадение. Такой подход эффективен для небольших таблиц, но становится крайне медленным, когда речь идет о тысячах или десятках тысяч строк.
Индекс в ТаблицеЗначений работает как тот самый алфавитный указатель. Платформа 1С заранее создает специальную, упорядоченную структуру данных, которая напрямую связывает значения в индексируемой колонке с номерами строк, где эти значения встречаются. Когда вы выполняете поиск по такой колонке, система не перебирает всю таблицу, а мгновенно обращается к индексу и получает нужные номера строк. Это многократно ускоряет операции поиска, особенно в больших объемах данных.
Таким образом, главная и, по сути, единственная задача индексов — радикальное ускорение поиска строк с помощью методов Найти() и НайтиСтроки().
// Создание таблицы и добавление колонки
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номенклатура");
ТЗ.Колонки.Добавить("Количество");
// ... код заполнения таблицы тысячами строк ...
// Создание индекса по колонке "Номенклатура"
ТЗ.Индексы.Добавить("Номенклатура");
// Теперь поиск по этой колонке будет работать очень быстро
НайденнаяСтрока = ТЗ.Найти("Товар123", "Номенклатура");
Казалось бы, если индексы так хороши, почему бы не создавать их всегда? Ответ кроется в том, что за ускорение поиска приходится платить. Поэтому применять индексирование нужно осознанно, при соблюдении следующих условий:
Важно понимать, как именно методы поиска взаимодействуют с индексами, особенно когда поиск нужно выполнить по нескольким колонкам. Здесь есть ключевое различие.
Метод Найти()
Этот метод предназначен для поиска первой попавшейся строки, удовлетворяющей условию. Он может использовать индекс, но только по одной колонке. Даже если вы передадите в него для поиска структуру с несколькими полями, или создадите составной индекс, Найти() проигнорирует его и будет выполнять полный перебор. Индекс будет задействован только если вы ищете по одной колонке, по которой ранее был создан простой индекс.
// Индекс будет использован
ИндексПоСотруднику = ТЗ.Индексы.Добавить("Сотрудник");
НайденнаяСтрока = ТЗ.Найти("Иванов", "Сотрудник");
// Индекс НЕ будет использован, будет полный перебор
Отбор = Новый Структура;
Отбор.Вставить("Сотрудник", "Иванов");
Отбор.Вставить("Отдел", "Отдел продаж");
НайденнаяСтрока = ТЗ.Найти(Отбор);
Метод НайтиСтроки()
Этот метод возвращает массив всех строк, удовлетворяющих отбору. Его главное преимущество в том, что он умеет эффективно работать с составными индексами — индексами, построенными сразу по нескольким колонкам.
Чтобы НайтиСтроки() задействовал индекс, нужно выполнить два условия:
Посмотрим на пример:
// Создаем таблицу
ТаблицаДокументов = Новый ТаблицаЗначений;
ТаблицаДокументов.Колонки.Добавить("Контрагент");
ТаблицаДокументов.Колонки.Добавить("Договор");
ТаблицаДокументов.Колонки.Добавить("Сумма");
// ... заполняем таблицу ...
// Создаем составной индекс по двум колонкам
ТаблицаДокументов.Индексы.Добавить("Контрагент, Договор");
// Готовим структуру для поиска
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Договор", НужныйДоговор); // Порядок не важен
СтруктураОтбора.Вставить("Контрагент", НужныйКонтрагент);
// Выполняем поиск. Он будет очень быстрым, т.к. используется составной индекс.
НайденныеСтроки = ТаблицаДокументов.НайтиСтроки(СтруктураОтбора);
Если бы мы искали только по полю "Контрагент", то составной индекс "Контрагент, Договор" не был бы использован. Для этого потребовался бы отдельный простой индекс по колонке "Контрагент".
Ускорение поиска — это лишь одна сторона медали. Использование индексов влечет за собой определенные накладные расходы, которые важно учитывать.
Добавить(), Вставить()), удаляете (Удалить()) или изменяете значение в индексированной колонке, платформа вынуждена перестраивать индекс. На больших таблицах с массовыми операциями по изменению данных это может привести к заметному падению производительности. Общее правило: сначала полностью заполните и обработайте таблицу, и только потом, перед началом поисковых операций, создавайте индексы.
Свернуть(). Если после сворачивания таблицы вам снова потребуется выполнять по ней частый поиск, не забудьте создать индексы заново.
Скопировать() индексы переносятся в новую таблицу только при полном копировании (без указания колонок или отбора). Если вы копируете только часть колонок, индексы в новой таблице придется создавать вручную.
В заключение, проанализируем ситуацию. Индексы в ТаблицеЗначений — это мощный инструмент оптимизации. Они незаменимы при работе с большими объемами данных, когда требуется выполнять множество поисковых запросов. Однако их применение должно быть взвешенным и оправданным. Всегда оценивайте размер таблицы, частоту поиска и накладные расходы на модификацию данных, чтобы добиться максимального прироста производительности вашего кода.