При работе в управляемом интерфейсе 1С:Предприятия 8.3 пользователи часто сталкиваются с ситуацией, когда при вводе символов в поле ввода или ячейку табличной части программа зависает на несколько секунд перед тем, как показать выпадающий список подсказок. Особенно ярко эта задержка проявляется в момент, когда введенных символов заведомо нет в базе данных. Проанализируем технические причины такого поведения СУБД и платформы, а также разберем по шагам практические способы оптимизации быстрого выбора.
Чтобы понять природу проблемы, выясним, какие процессы происходят на стороне сервера приложений и базы данных при вводе текста в поле:
СпособПоискаСтрокиПриВводеПоСтроке установлено значение Любая часть, платформа при отсутствии настроенного полнотекстового поиска генерирует SQL-запрос с конструкцией LIKE '%введенный_текст%'. В этом случае B-Tree индекс СУБД по наименованию не может быть использован для поиска по диапазону (Index Seek). СУБД начинает последовательное сканирование всей таблицы (Table Scan или Index Scan). Если соответствие находится в первых строках таблицы, результат возвращается быстро. Однако если введенного значения в базе нет, СУБД приходится считывать всю таблицу до конца, создавая высокую нагрузку на дисковую подсистему и вызывая долгое зависание интерфейса.Индексировать, поиск по ним неизбежно приводит к замедлению.БыстрыйВыбор, поведение списка выбора меняется: платформа пытается сразу подготовить и отобразить выпадающий список всех доступных элементов или сопоставить введенные данные с полным объемом выборки.Рассмотрим самое простое решение, которое не требует изменения программного кода и решает проблему зависания на уровне метаданных:
СпособПоискаСтрокиПриВводеПоСтроке и переключим его со значения Любая часть на значение С начала строки. При таком режиме платформа формирует SQL-условие LIKE 'текст%', что позволяет СУБД мгновенно использовать стандартный индекс по наименованию или коду даже при полном отсутствии совпадений в таблице.БыстрыйВыбор (установим свойство в значение Нет). Это предотвратит принудительную инициализацию тяжелых списков при активации поля.ПоляВводаПоСтроке справочника. Рекомендуется оставить там только стандартные реквизиты Наименование и Код. Если в списке присутствуют дополнительные реквизиты, убедимся, что в их свойствах включено индексирование (значение Индексировать или Индексировать с доп. упорядочиванием).Если бизнес-логика требует гибкого подбора (например, поиск сразу по нескольким реквизитам или по части строки), наиболее надежным решением является переопределение механизма получения подсказок в модуле менеджера справочника.
Разберем реализацию этого механизма на практике. Откроем модуль менеджера справочника и опишем предопределенную процедуру ОбработкаПолученияДанныхВыбора:
Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
// Отключаем стандартный механизм поиска платформы
СтандартнаяОбработка = Ложь;
// Создаем список для возврата найденных значений
ДанныеВыбора = Новый СписокЗначений;
// Если строка поиска пустая, ничего не ищем
Если ПустаяСтрока(Параметры.СтрокаПоиска) Тогда
Возврат;
КонецЕсли;
// Формируем легковесный запрос с обязательным ограничением выборки
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 20
| Спр.Ссылка КАК Ссылка,
| Спр.Наименование КАК Наименование
|ИЗ
| Справочник.Имена КАК Спр
|ГДЕ
| НЕ Спр.ПометкаУдаления
| И (Спр.Наименование ПОДОБНО &СтрокаПоискаСНачала
| ИЛИ Спр.Код ПОДОБНО &СтрокаПоискаСНачала)
|
|УПОРЯДОЧИТЬ ПО
| Спр.Наименование";
Запрос.УстановитьПараметр("СтрокаПоискаСНачала", Параметры.СтрокаПоиска + "%");
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Наименование);
КонецЦикла;
КонецПроцедуры
Обратим внимание на ключевые особенности этого подхода:
СтандартнаяОбработка = Ложь, предотвращая стандартное ресурсоемкое сканирование таблиц.ВЫБРАТЬ ПЕРВЫЕ 20 жестко ограничивает объем возвращаемых на клиент данных и время выполнения запроса на сервере СУБД.&СтрокаПоиска + "%") задействует существующие индексы, обеспечивая миллисекундный отклик даже на таблицах с миллионами записей.Если в конфигурации принципиально важно сохранить платформенный поиск по любой части строки без написания собственного кода, необходимо обеспечить корректную работу вспомогательных подсистем:
ОбновлениеИндексаППД (должно запускаться с интервалом раз в 1–5 минут) и СлияниеИндексовППД (обычно запускается один или два раза в сутки). При нарушении их работы выполним полное перестроение индекса полнотекстового поиска через меню администрирования.WITH FULLSCAN), чтобы оптимизатор запросов СУБД строил корректные планы выборок.Применение описанных настроек позволяет полностью устранить многосекундные задержки интерфейса и обеспечить плавный, отзывчивый ввод данных для пользователей.