Как использовать функцию ВЫРАЗИТЬ в запросе 1С для оптимизации и работы с типами

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

В практике разработки на платформе 1С:Предприятие 8 часто возникает ситуация, когда запрос начинает работать медленно или система выдает предупреждения об "излишнем разыменовании". Одной из ключевых функций, помогающих решить эти проблемы, является ВЫРАЗИТЬ. Давайте разберем подробно, как и когда её применять, чтобы ваши запросы летали, а код соответствовал стандартам разработки.

Что такое излишнее разыменование и чем оно опасно?

Разыменование — это обращение к реквизитам через точку (например, Остатки.Номенклатура.ВидНоменклатуры). На первый взгляд, это очень удобно, но на уровне СУБД (SQL) каждое такое обращение превращается в левое соединение (LEFT JOIN). Рассмотрим ситуацию, когда поле имеет составной тип. Например, поле Регистратор может содержать ссылки на 20 различных видов документов. Если мы напишем Регистратор.Дата, SQL-сервер будет вынужден соединить основную таблицу со всеми 20 таблицами документов, чтобы найти поле Дата. Это создает колоссальную нагрузку на план запроса.

Функция ВЫРАЗИТЬ позволяет явно указать системе: "В данном поле сейчас находится объект конкретного типа". Это ограничивает количество соединений в SQL-запросе до одного нужного нам типа.

Применение ВЫРАЗИТЬ для полей составного типа

Если в вашем запросе фигурирует поле, которое может принимать значения разных типов, использование ВЫРАЗИТЬ является обязательным требованием стандартов 1С. Разберем по шагам, как это реализовать в тексте запроса.

Предположим, у нас есть регистр, где поле Номенклатура теоретически может быть составным (например, Справочник.Номенклатура и Справочник.Услуги). Чтобы получить ВидНоменклатуры, нам следует написать:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Остатки.Номенклатура КАК Справочник.Номенклатура).ВидНоменклатуры КАК ВидНоменклатуры
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки

В этом примере платформа поймет, что нужно строить соединение только с таблицей справочника Номенклатура, игнорируя остальные возможные типы данных в этом поле.

Оптимизация работы со строками неограниченной длины

Еще одна критически важная область применения функции — работа со строками. В 1С строки могут быть ограниченной длины (например, 10, 50, 200 символов) и неограниченной (хранятся в базе как CLOB/NTEXT). СУБД не умеет эффективно индексировать, группировать или упорядочивать строки неограниченной длины.

Если вам нужно сгруппировать результат запроса по многострочному полю (например, "Комментарий" или "Описание"), вы обязательно должны его обрезать:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Заказы.Комментарий КАК СТРОКА(250)) КАК КомментарийКратко,
    СУММА(Заказы.СуммаДокумента) КАК Сумма
ИЗ
    Документ.ЗаказПокупателя КАК Заказы
СГРУППИРОВАТЬ ПО
    ВЫРАЗИТЬ(Заказы.Комментарий КАК СТРОКА(250))

Проанализируем этот момент: без функции ВЫРАЗИТЬ такой запрос в некоторых версиях СУБД просто выдаст ошибку, так как группировка по неограниченным полям запрещена.

Использование ВЫРАЗИТЬ в условиях и виртуальных таблицах

Часто возникает вопрос: можно ли использовать эту функцию в параметрах виртуальных таблиц? Да, это не только можно, но и нужно для ускорения выборки. Рассмотрим пример, когда мы хотим отобрать остатки только по тем объектам, тип которых нам заранее известен в составном поле.

Хотя чаще всего ВЫРАЗИТЬ используется в списке выбора (после слова ВЫБРАТЬ), её также можно встретить в условиях ГДЕ. Это помогает отсечь лишние типы данных еще до формирования итогового результата.

Альтернатива: Явное соединение таблиц

Если ваш наставник или "специалист" настаивает на том, что обращение через точку вообще нельзя использовать, даже с ВЫРАЗИТЬ, существует более "чистый" с точки зрения производительности метод — внутреннее или левое соединение. Разберем, как переписать запрос с использованием явного соединения:


ВЫБРАТЬ
    Остатки.Номенклатура КАК НоменклатураСсылка,
    СпрНоменклатура.ВидНоменклатуры КАК ВидНоменклатуры
ИЗ
    РегистрНакопления.ТоварыНаСкладах.Остатки КАК Остатки
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
    ПО Остатки.Номенклатура = СпрНоменклатура.Ссылка

Этот способ считается максимально прозрачным для оптимизатора SQL. Мы явно указываем, с какой таблицей соединяемся, и выбираем данные уже из соединенной таблицы СпрНоменклатура, а не "через точку" от основной таблицы остатков.

Важные нюансы при работе с типами данных

Рассмотрим несколько специфических ситуаций, которые помогут вам избежать типичных ошибок:

  1. Обработка NULL: Помните, что функция ВЫРАЗИТЬ не заменяет NULL на пустое значение. Если в поле лежит NULL, результатом функции тоже будет NULL. Для подстановки значения по умолчанию используйте связку ЕСТЬNULL(ВЫРАЗИТЬ(Поле КАК Тип), ЗначениеЗамены).
  2. Определение типов в UNION: Когда вы используете ОБЪЕДИНИТЬ ВСЕ, типы колонок результирующей таблицы определяются по первой выборке. Если в первой таблице в колонке стоит NULL, платформа может ошибиться с типом. Используйте ВЫРАЗИТЬ(NULL КАК Число(15,2)) в первой части объединения, чтобы жестко задать структуру.
  3. Временные таблицы: При создании временных таблиц через ПОМЕСТИТЬ, использование ВЫРАЗИТЬ гарантирует, что в индексах будут использованы компактные и быстрые типы данных. Например, приведение к СТРОКА(50) вместо СТРОКА(1024) значительно сэкономит оперативную память сервера.

Сортировка по представлению или по ссылке?

Выясним причину, почему иногда сортировка работает странно. Если вы сортируете по полю Номенклатура, система сортирует по внутренним идентификаторам (GUID). Чтобы отсортировать по наименованию, часто советуют использовать ВЫРАЗИТЬ(Поле КАК СТРОКА), но в 1С есть более правильный способ — использование поля Наименование. Однако для документов, у которых нет единого поля "Наименование", приведение к строке может помочь получить текстовое представление для вывода в отчет.

Резюме по использованию ВЫРАЗИТЬ

Подведем итог нашему анализу. Использовать функцию ВЫРАЗИТЬ следует в следующих случаях:

Соблюдение этих простых правил не только "успокоит" автоматизированные проверки кода и строгих руководителей, но и реально повысит стабильность вашей информационной системы при росте объемов данных.

← На главную