В процессе разработки и поддержки крупных информационных систем на платформе 1С:Предприятие часто возникает ситуация, когда объем данных в одном документе (например, в «Установке цен номенклатуры») достигает нескольких тысяч строк. В таких случаях стандартные механизмы поиска начинают работать медленно, вызывая задержки в 2–3 минуты. Разберем подробно, как работает индексация табличных частей, почему включение флажка «Индексировать» в конфигураторе не всегда решает проблему мгновенно, и какие механизмы платформы задействуются в разных сценариях.
Когда мы устанавливаем свойство реквизита табличной части «Индексировать» (с поддержкой полнотекстового поиска или без), платформа 1С при обновлении конфигурации базы данных инициирует создание индекса непосредственно в СУБД. Проанализируем, почему этот процесс может казаться «незаметным» или проходить слишком быстро:
ONLINE. Это означает, что база данных остается доступной, а индекс строится параллельно. Если данных не миллионы строк, 1С пролетает этап реструктуризации крайне быстро.[Ссылка + Реквизит] или [Реквизит + Ссылка]. Это необходимо для того, чтобы SQL-сервер мог быстро отфильтровать строки, принадлежащие конкретному документу.SQL Management Studio. Таблицы табличных частей документов имеют префикс _DocumentChng.... Найдя нужную таблицу, мы увидим список индексов в соответствующей ветке дерева объекта.Рассмотрим ситуацию, на которую часто жалуются разработчики: индекс включен, но НайтиСтроки() в открытой форме документа все равно «тормозит». Разберем причину этого явления. Платформа 1С разделяет работу с данными на два уровня:
1. Объектная техника (Данные в памяти): Когда документ открыт в форме, все строки его табличной части уже считаны из базы данных и находятся в оперативной памяти (в коллекции ТабличнаяЧасть или в ТаблицеЗначений, если речь идет о программной обработке). Когда пользователь выполняет поиск в экранной форме или программист использует метод НайтиСтроки(), система не обращается к SQL-серверу. Она перебирает данные прямо в памяти. Индекс, созданный в конфигураторе для SQL, здесь абсолютно бесполезен.
2. Запросная техника: Индекс в метаданных будет эффективно работать только в том случае, если поиск выполняется через объект Запрос. Например:
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ Ссылка ИЗ Документ.УстановкаЦенНоменклатуры.Товары ГДЕ Номенклатура = &Номенклатура";
// Здесь индекс SQL будет задействован максимально эффективно
Если нам необходимо ускорить поиск именно в оперативной памяти (например, при заполнении документа, когда строк уже много), мы должны использовать механизмы индексации коллекций. Рассмотрим пример индексации ТаблицыЗначений:
// Выгружаем ТЧ в таблицу значений для быстрой обработки
тзТовары = Товары.Выгрузить();
// Создаем индекс в памяти. Это работает очень быстро
тзТовары.Индексы.Добавить("Номенклатура");
// Теперь поиск через НайтиСтроки будет мгновенным
ПараметрыОтбора = Новый Структура("Номенклатура", ИскомыйТовар);
НайденныеСтроки = тзТовары.НайтиСтроки(ПараметрыОтбора);
Важный момент: Для обычных форм в документе «Установка цен номенклатуры» часто используется не стандартная табличная часть, а дерево значений или динамически формируемая таблица цен. В этом случае стандартная индексация реквизита в дереве объектов метаданных вообще не имеет смысла для интерфейса.
Проанализируем совет использовать КритерииОтбора. Это специальный объект метаданных, который позволяет быстро находить документы по значению определенного реквизита.
Если мы добавим реквизит табличной части в состав критерия отбора (например, «ПоискПоНоменклатуре»), платформа автоматически установит для этого реквизита свойство индексации. Это гарантирует, что в базе данных будет создан индекс, оптимизированный для поиска ссылок на документы. Если ваша задача — быстро найти, в каких документах «Установка цен» встречается конкретная позиция товара, критерии отбора — лучший инструмент.
Выясним, что означает флаг «Обрабатывать табличные части» в стандартной групповой обработке справочников и документов (часто используемой в обычном интерфейсе). Это важный инструмент для массовых изменений данных:
Если поиск в табличной части на 5000–6000 строк занимает 2–3 минуты, скорее всего, проблема не в отсутствии индекса, а в алгоритме обработки событий. Проанализируем возможные «узкие места»:
ПриАктивизацииСтроки, которые инициируют тяжелое обновление связанных элементов формы. Попробуйте на время поиска отключать обработчики событий или использовать ЭтаФорма.ОбновлениеОтображения(Ложь).Таким образом, для решения проблемы медленного поиска мы должны сначала определить, где именно происходит задержка: на уровне SQL при выполнении запроса или на уровне интерфейса в памяти. В зависимости от этого выбирается метод: индексация в метаданных для запросов или использование Индексы.Добавить() для коллекций в оперативной памяти.