Есть ли смысл использовать оператор ПОДОБНО без спецсимволов в запросах 1С и почему результаты могут отличаться от оператора равенства?

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

При написании запросов в платформе 1С:Предприятие разработчики часто сталкиваются с дилеммой выбора операторов сравнения строк. На первый взгляд может показаться, что использование оператора ПОДОБНО (аналог LIKE в SQL) без использования специальных символов маски (таких как % или _) эквивалентно обычному оператору равенства =. Однако на практике эти два оператора работают на уровне СУБД совершенно по-разному. В этой статье мы подробно разберем, почему они могут возвращать разные результаты, как это влияет на производительность системы и развенчаем популярные мифы, связанные с регистрозависимостью.

1. Главная причина различий: Проблема концевых пробелов (Trailing Spaces)

Рассмотрим ситуацию, когда при поиске по строковому реквизиту один запрос с оператором = возвращает данные, а аналогичный запрос с оператором ПОДОБНО выдает пустой результат. Выясним причину этого поведения, которая кроется в стандартах работы СУБД со строковыми типами данных.

Согласно стандарту ANSI SQL-92, сравнение строк с помощью оператора равенства = происходит по особым правилам. Перед сопоставлением двух строк СУБД автоматически дополняет более короткую строку пробелами справа, чтобы их физическая длина сравнялась, и только после этого выполняет посимвольное сравнение.

Проанализируем простой пример. Допустим, мы сравниваем две строки:

  1. Строка А: "Иванов" (длина 6 символов)
  2. Строка Б: "Иванов " (длина 7 символов, на конце пробел)

При использовании оператора равенства выражение будет обработано следующим образом:


// СУБД приводит строки к одной длине, виртуально дополняя первую пробелом:
"Иванов " = "Иванов " // Результат: ИСТИНА (True)

Теперь посмотрим, что происходит при использовании оператора ПОДОБНО. Этот оператор предназначен для поиска по шаблону, поэтому правила дополнения строк пробелами к нему не применяются. Для СУБД любой пробел в шаблоне (в правой части выражения) является значащим символом, который должен быть найден в исходной строке один в один.


// Сравнение по шаблону без автодополнения пробелами:
"Иванов" ПОДОБНО "Иванов " // Результат: ЛОЖЬ (False)

Таким образом, если пользователь при вводе поискового запроса случайно нажал клавишу пробела в конце слова, или если в самой базе данных содержатся строки с невидимыми концевыми пробелами, оператор равенства = успешно найдет соответствие, а оператор ПОДОБНО без спецсимволов вернет пустой результат. Это ключевое различие, которое напрямую влияет на корректность работы ваших алгоритмов поиска.

2. Особенности работы со строками фиксированной длины

В платформе 1С существуют строки переменной длины и строки фиксированной длины. На уровне СУБД строки фиксированной длины хранятся в полях типа CHAR, а переменной — в полях типа VARCHAR. Поля типа CHAR всегда физически заполняются пробелами до максимального размера, указанного в метаданных.

Хотя платформа 1С берет на себя множество задач по унификации работы с СУБД, при выполнении сложных запросов (например, при соединении таблиц по строковым полям) разница в обработке типов CHAR и VARCHAR может приводить к неожиданному поведению. Оператор равенства = отрабатывает такие сравнения предсказуемо и стабильно благодаря все тому же стандарту ANSI SQL-92, в то время как поведение ПОДОБНО может сильно зависеть от конкретной СУБД и физического наполнения полей пробелами.

3. Производительность запросов и использование индексов (SARGability)

Рассмотрим, как выбор оператора влияет на скорость выполнения запроса оптимизатором СУБД (будь то Microsoft SQL Server, PostgreSQL, IBM DB2 или Oracle). Это критически важный аспект при работе с высоконагруженными или крупными базами данных.

В теории баз данных существует понятие SARGable (Search Argument Able) — это свойство условий в запросе, которое позволяет оптимизатору эффективно использовать существующие индексы для быстрого поиска данных.

  1. Оператор равенства «=»: является классическим SARGable-условием. СУБД мгновенно понимает, какое конкретное значение требуется найти, и выполняет операцию Index Seek (поиск по индексу). Это самый быстрый способ получения данных, который работает практически мгновенно даже на таблицах с миллионами записей.
  2. Оператор «ПОДОБНО» (LIKE): заставляет СУБД анализировать выражение как текстовый шаблон. Даже если шаблон не содержит спецсимволов (например, ПОДОБНО "Кока-Кола"), оптимизатор запросов вынужден тратить дополнительные ресурсы на анализ строки.
    • В современных СУБД (например, MS SQL Server) оптимизатор достаточно «умен», чтобы на лету упростить выражение ПОДОБНО "Значение" до обычного = "Значение" и построить оптимальный план запроса.
    • Однако в других СУБД (например, в PostgreSQL) или при написании сложных вложенных запросов и соединений оптимизатор может не справиться с таким упрощением. Вместо быстрого поиска по индексу (Index Seek) СУБД применит сканирование всей таблицы или индекса (Table Scan / Index Scan). Это приведет к полной вычитке данных с диска и катастрофическому падению производительности всей системы.

Именно поэтому использование ПОДОБНО при соединении таблиц в условиях ПО категорически не рекомендуется стандартами разработки фирмы 1С. Соединения должны выполняться исключительно по оператору равенства =.

4. Развенчание мифа о регистрозависимости сравнения

Среди начинающих разработчиков часто циркулирует заблуждение, что оператор ПОДОБНО позволяет выполнять регистронезависимый поиск там, где оператор равенства = якобы чувствителен к регистру. Это абсолютно неверное представление о работе СУБД.

Регистрозависимость любого сравнения строк в запросах 1С определяется исключительно настройками сортировки (Collation) базы данных в СУБД, но никак не выбранным оператором запроса.

Рассмотрим два сценария настройки базы данных:

Таким образом, оператор ПОДОБНО сам по себе не обладает магическим свойством игнорировать регистр символов, если это запрещено глобальными настройками базы данных.

5. Практические примеры применения и рекомендации

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

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


// НЕКОРРЕКТНЫЙ ВАРИАНТ: Использование ПОДОБНО без спецсимволов
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Контрагенты.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |   Контрагенты.Наименование ПОДОБНО &Наименование";

// Если в переменной ИмяПоиска окажется лишний пробел на конце, запрос ничего не найдет
ИмяПоиска = "ООО Ромашка "; 
Запрос.УстановитьПараметр("Наименование", ИмяПоиска);
Результат = Запрос.Выполнить();

А теперь напишем правильный, отказоустойчивый и максимально быстрый код с использованием оператора равенства:


// ПРАВИЛЬНЫЙ ВАРИАНТ: Использование оператора равенства
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Контрагенты.Ссылка КАК Ссылка
    |ИЗ
    |   Справочник.Контрагенты КАК Контрагенты
    |ГДЕ
    |   Контрагенты.Наименование = &Наименование";

// Рекомендуется всегда очищать входные параметры от нежелательных пробелов с помощью функции СокрЛП()
ИмяПоиска = СокрЛП("ООО Ромашка "); 
Запрос.УстановитьПараметр("Наименование", ИмяПоиска);
Результат = Запрос.Выполнить();

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

Подводя итог нашему анализу, можно с уверенностью сказать: использование оператора ПОДОБНО без спецсимволов не имеет никаких практических или технических преимуществ перед оператором равенства «=». Напротив, такое написание кода несет в себе скрытые риски:

Используйте оператор ПОДОБНО только по его прямому назначению — когда вам действительно требуется выполнить нечеткий поиск по маске с использованием спецсимволов % (любое количество произвольных символов) или _ (один произвольный символ). Во всех остальных случаях вашим основным инструментом всегда должен оставаться классический оператор равенства =.

← На главную