Как ускорить поиск по вхождению строки и ФИО в базе 1С?

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

При работе с большими справочниками (например, справочником физических лиц на 500 000 и более записей) разработчики часто сталкиваются с проблемой медленного поиска. Пользователи привыкли вводить подстроку «на лету» и ожидать мгновенных результатов. Однако попытки преобразовать текст в числовые коды или использовать нестандартные алгоритмы обычно не дают желаемого эффекта. Рассмотрим причины высокой нагрузки на СУБД и проанализируем проверенные способы оптимизации поиска.

Почему поиск по подстроке работает медленно?

Главная причина низкой скорости работы запросов с оператором ПОДОБНО "%строка%" заключается в особенностях работы индексации в СУБД на основе B-Tree (сбалансированных деревьев). Когда в начале шаблона поиска стоит символ процента (%), индекс базы данных становится бесполезным. СУБД не может определить начальную точку поиска в индексе и вынуждена выполнять полное сканирование таблицы (Full Table Scan).

Для справочника в 500 000 записей это означает, что при каждом нажатии клавиши система последовательно вычитывает все строки из диска или оперативной памяти. Если на форме реализован фоновый поиск при вводе текста, то на каждый символ отправляется отдельный запрос, выдерживающий огромную пиковую нагрузку на сервер и дисковую подсистему.

Решение 1. Переход на префиксный поиск (без первого процента)

В абсолютном большинстве бизнес-сценариев пользователи начинают ввод с первых букв фамилии, имени или отчества. Если убрать первый символ процента из условия запроса, СУБД сможет задействовать B-Tree индекс по строковому полю.

Запрос вида ГДЕ ФИО ПОДОБНО "Мороз%" выполняется практически мгновенно, так как SQL-сервер переходит по индексу сразу к нужной ветке и считывает только совпавшие строки.

Решение 2. Токенизация и хранение компонентов ФИО

Если требуется искать человека не только по фамилии, но и по имени или отчеству отдельно, эффективным решением является разбиение ФИО на компоненты (токены) при записи объекта.

Разберем алгоритм настройки этого подходу по шагам:

  1. Создаем дополнительную табличную часть или регистр сведений КомпонентыФИО с индексированным реквизитом Значение (тип Строка фиксированной длины).
  2. При записи физического лица разбиваем полное ФИО на отдельные слова (фамилия, имя, отчество), приводим их к одному регистру и записываем отдельными строками.
  3. При поиске формируем запрос с условием префиксного поиска по табличной части без первого процента:

ВЫБРАТЬ РАЗЛИЧНЫЕ
	ТЧ.Ссылка КАК ФизическоеЛицо
ИЗ
	Справочник.ФизическиеЛица.КомпонентыФИО КАК ТЧ
ГДЕ
	ТЧ.Значение ПОДОБНО &СтрокаПоиска + "%"

Этот подход позволяет находить физическое лицо по любому из слов (имени, фамилии или отчеству), сохраняя максимальную скорость работы за счет использования стандартных B-Tree индексов СУБД.

Решение 3. Использование полнотекстового поиска 1С

В платформе 1С существует встроенный механизм полнотекстового поиска (ПТП). В отличие от классических индексов B-Tree, полнотекстовый индекс построен по принципу инвертированного индекса (N-граммы и словари), что делает его идеально приспособленным для работы с подстроками и текстом.

Преимущества использования полнотекстового поиска:

  1. Включение поиска по реквизиту выполняется установкой одного свойства в конфигураторе без усложнения структуры данных.
  2. Высокая скорость поиска даже при наличии сотен тысяч и миллионов записей.
  3. Поддержка поиска по части слова и морфологии.

Вызов полнотекстового поиска программно осуществляется через менеджер полнотекстового поиска:


СписокИсточников = Новый СписокЗначений;
СписокИсточников.Добавить(Метаданные.Справочники.ФизическиеЛица);

ЗапросПТП = ПолнотекстовыйПоиск.СоздатьСписок(&СтрокаПоиска, 20);
ЗапросПТП.ОбластьПоиска = СписокИсточников;

Если ЗапросПТП.ПерваяЧасть() Тогда
	Для Каждого ЭлементИз Результат Цикл
		// Обработка найденных объектов
	КонецЦикла;
КонецЕсли;

Решение 4. Использование механизма триграмм (N-grams)

Если полнотекстовый поиск по каким-то причинам не подходит, а искать нужно именно по любой подстроке внутри слова, применяется технология разбиения текста на триграммы (сочетания из 3 символов).

Проанализируем принцип работы триграмм:

  1. Строка «Мороз» расщепляется на триграммы: «мор», «оро», «роз».
  2. Триграммы сохраняются в отдельном индексированном регистре сведений с привязкой к ссылке на физическое лицо.
  3. При вводе поискового запроса «рози» строка также разбивается на триграммы («роз», «ози»).
  4. В запросе ищутся точные совпадения по ключу триграммы через оператор В (...), что сокращает массив проверяемых записей с 500 000 до нескольких единиц, после чего выполняется финальная проверка.

Оптимизация пользовательского ввода на форме

Помимо оптимизации запросов к базе данных, важно правильно настроить поведение формы при вводе текста:

  1. Задержка вызова (Debounce): Не отправляйте запрос на сервер при каждом нажатии клавиши. Настройте таймер с задержкой 300–500 мс после последнего введенного символа.
  2. Ограничение по длине строки: Не запускайте поиск, пока пользователь не ввел хотя бы 3 символа.
  3. Ограничение объема выборки: Всегда используйте инструкцию ВЫБРАТЬ ПЕРВЫЕ N в запросах поиска. Это позволяет СУБД прервать сканирование таблицы сразу после нахождения первых совпадений.
← На главную