Как оптимизировать поиск в больших таблицах значений и правильно использовать индексы в 1С

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

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

Постановка задачи и анализ стандартных методов

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

Проанализируем основные методы поиска (а также изучим производительность способов обхода по группировке), доступные для объекта ТаблицаЗначений:

  1. Найти(Значение, Колонки) — возвращает первую найденную строку или Неопределено.
  2. НайтиСтроки(СтруктураОтбора) — возвращает массив всех строк, соответствующих условию.

Выясним причину низкой скорости: без специальных настроек эти методы выполняют линейный перебор строк. Чтобы ускорить этот процесс, в 1С предусмотрен механизм индексации.

Механизм использования индексов в Таблице Значений

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

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


// Предположим, у нас есть ТаблицаТоваров с колонками "Артикул" и "Склад"
ТаблицаТоваров.Индексы.Добавить("Артикул");
// Можно создавать составные индексы для поиска по нескольким полям
ТаблицаТоваров.Индексы.Добавить("Артикул, Склад");

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

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

Проанализируем, как ведут себя методы поиска при наличии индекса. Метод Найти() использует индекс только в том случае, если поиск ведется по одной колонке, и для этой колонки создан индекс. Однако максимальную эффективность индексы показывают при использовании метода НайтиСтроки().

Разберем пример эффективного поиска по нескольким полям:


// Подготовка структуры отбора
Отбор = Новый Структура;
Отбор.Вставить("Артикул", ИскомыйАртикул);
Отбор.Вставить("Склад", ИскомыйСклад);

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

Если НайденныеСтроки.Количество() > 0 Тогда
    СтрокаРезультат = НайденныеСтроки[0]; // Берем первое совпадение
КонецЕсли;

В данном примере, если индекс по колонкам "Артикул, Склад" был предварительно добавлен, поиск отработает практически мгновенно, независимо от того, миллион строк в таблице или десять.

Оптимизация через использование соответствия (Кэширование)

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

Разберем, как реализовать этот подход:

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

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


КэшТоваров = Новый Соответствие;
Для Каждого Стр Из ТаблицаТоваров Цикл
    КэшТоваров.Вставить(Стр.Артикул, Стр);
КонецЦикла;

// Теперь поиск выполняется мгновенно
НужнаяСтрока = КэшТоваров.Получить(ИскомыйАртикул);
Если НужнаяСтрока <> Неопределено Тогда
    // Работаем со строкой
КонецЕсли;

Этот метод потребляет больше оперативной памяти, но обеспечивает максимально возможную скорость доступа к данным в языке 1С.

Практические советы по работе с большими коллекциями

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

Выясним, когда стоит использовать запросы к таблицам значений. Рассмотрим пример, где мы передаем таблицу в запрос:


Запрос = Новый Запрос;
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
Запрос.Текст = "ВЫБРАТЬ * ПОМЕСТИТЬ ВТ_Данные ИЗ &ТЗ КАК ТЗ;
               |ВЫБРАТЬ * ИЗ ВТ_Данные ГДЕ Артикул = &Артикул";
Запрос.УстановитьПараметр("ТЗ", ТаблицаТоваров);
Запрос.УстановитьПараметр("Артикул", ИскомыйАртикул);
РезультатЗапроса = Запрос.Выполнить();

Этот метод медленнее, чем НайтиСтроки() с индексом, из-за накладных расходов на передачу данных в СУБД (или во временное хранилище), но он незаменим при выполнении сложных аналитических выборок. Для контроля использования памяти и автоматического удаления временных таблиц в сложных пакетах подойдёт обработка для расстановки инструкций УНИЧТОЖИТЬ во временных таблицах.

Резюме и выводы

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

  1. Для однократного поиска используйте метод Найти().
  2. Для многократного поиска по одной или нескольким колонкам обязательно предварительно создавайте Индексы.
  3. Если требуется максимальное быстродействие при поиске по уникальному ключу, используйте объект Соответствие в качестве кэша.
  4. Всегда замеряйте производительность: на малых объемах данных (до 1000 строк) разница в методах будет неощутима, но на больших — она станет критической.

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

← На главную