В процессе разработки часто возникает задача реализовать поиск или отбор данных не по одному, а сразу по нескольким полям справочника. Например, когда у города есть основное наименование и альтернативное (Наименование2), и нам нужно найти записи, соответствующие строке поиска в любом из этих полей. Рассмотрим детально, как правильно составить такой запрос, как его оптимизировать и какие нюансы работы с расширениями могут возникнуть.
Самый простой и очевидный способ — использование оператора ИЛИ в условии запроса. Рассмотрим пример, когда нам нужно найти город по частичному совпадению в полях Наименование или Наименование2. Важно помнить, что секция ГДЕ в запросе указывается только один раз, а все условия внутри нее соединяются логическими операторами.
Проанализируем правильный синтаксис такого запроса:
"ВЫБРАТЬ
| нпгорода.Ссылка КАК Ссылка,
| нпгорода.Наименование КАК Наименование,
| нпгорода.Наименование2 КАК Наименование2
|ИЗ
| Справочник.НП_Города КАК нпгорода
|ГДЕ
| (нпгорода.Наименование ПОДОБНО &Город
| ИЛИ нпгорода.Наименование2 ПОДОБНО &Город)"
В данном примере мы используем скобки для группировки условий. Это хорошая практика, особенно если в запросе появятся дополнительные условия (например, отбор по пометке удаления). Использование оператора ПОДОБНО позволяет искать вхождения строк, если в параметр &Город будут переданы спецсимволы (например, "%").
При работе с большими справочниками (десятки и сотни тысяч записей) использование ИЛИ может значительно замедлить выполнение запроса. Это происходит потому, что СУБД (например, MS SQL Server) не всегда может эффективно использовать индексы по обоим полям одновременно, что приводит к полному сканированию таблицы (Table Scan).
Разберем более производительный подход — использование конструкции ОБЪЕДИНИТЬ. Мы разделяем один запрос на два независимых поиска, результаты которых затем «склеиваются».
"ВЫБРАТЬ
| нпгорода.Ссылка,
| нпгорода.Наименование,
| нпгорода.Наименование2
|ИЗ
| Справочник.НП_Города КАК нпгорода
|ГДЕ
| нпгорода.Наименование ПОДОБНО &Город
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| нпгорода.Ссылка,
| нпгорода.Наименование,
| нпгорода.Наименование2
|ИЗ
| Справочник.НП_Города КАК нпгорода
|ГДЕ
| нпгорода.Наименование2 ПОДОБНО &Город"
Почему это работает быстрее? Рассмотрим ситуацию: каждое условие по отдельности может использовать свой индекс (если они созданы для полей Наименование и Наименование2). СУБД выполняет два быстрых поиска по индексам (Index Seek) и объединяет результат. Если вы уверены, что результаты не пересекаются, используйте ОБЪЕДИНИТЬ ВСЕ — это еще быстрее, так как системе не придется тратить ресурсы на поиск и удаление дублей записей.
Эффективность поиска напрямую зависит от того, как вы используете маску поиска. Рассмотрим два варианта использования параметра:
"Москва%", система сможет использовать индекс. Это максимально быстрый вариант."%Москва%", индекс использоваться не будет. Системе придется прочитать каждую запись справочника, чтобы проверить условие.Для ускорения таких запросов убедитесь, что у реквизита Наименование2 в свойствах метаданных установлено значение Индексировать или Индексировать с дополнительным упорядочиванием. Поле Наименование индексируется платформой по умолчанию.
Иногда разработчики сталкиваются с тем, что Конструктор запросов не видит нужный справочник при работе в расширении конфигурации. Выясним основные причины этой ситуации:
Наименование2) также заимствованы в расширение.Важный совет: Старайтесь всегда использовать Конструктор запросов. Он помогает избежать синтаксических ошибок (как в случае с лишним словом ГДЕ) и автоматически подставляет правильные имена таблиц и полей с учетом префиксов расширений.
Если ваша задача — найти одну конкретную ссылку, а не строить сложный отчет, можно воспользоваться программными методами объекта СправочникиМенеджер. Однако помните об их ограничениях:
НайтиПоНаименованию() ищет только по стандартному полю Наименование.НайтиПоРеквизиту() позволяет искать по любому реквизиту, но только по одному за раз и только на полное соответствие (не по части слова).Для полноценного поиска по нескольким полям с использованием масок (ПОДОБНО) механизм запросов остается самым мощным и гибким инструментом в арсенале разработчика 1С.
Если справочник содержит огромное количество данных и пользователи часто ищут информацию по разным фрагментам слов, рассмотрим использование встроенного Полнотекстового поиска (ППП). Этот механизм работает быстрее обычных запросов, поддерживает морфологию (склонения) и умеет искать сразу по всем индексированным полям объекта одной командой. Для этого достаточно использовать метод ПолнотекстовыйПоиск.СоздатьСписок() и настроить соответствующие свойства в метаданных справочника.