При написании сложных запросов в 1С:Предприятие 8 программисты часто сталкиваются с проблемой "простыни" условий в блоке ГДЕ. Когда количество фильтров переваливает за десяток, становится трудно быстро определить, к какой логической части относится то или иное условие. Ситуация осложняется тем, что стандартный Конструктор запроса при сохранении часто "причесывает" код, удаляя лишние скобки и комментарии, которые разработчик расставил для удобства. Рассмотрим подробнее несколько подходов к решению этой задачи: от простых визуальных хаков до серьезных архитектурных изменений.
Один из самых простых способов, с которого часто начинают разработчики, — это вставка нейтральных условий, которые не влияют на результат выборки, но служат визуальными разделителями. Разберем, как это выглядит на практике:
ГДЕ Условие11
И Условие12
И ИСТИНА
И Условие21
И Условие22
И ИСТИНА
И Условие31
Такой подход позволяет отделить блоки однотипных условий друг от друга. Однако у него есть существенные недостатки. Во-первых, это все еще выглядит не слишком аккуратно. Во-вторых, опытные разработчики предостерегают от злоупотребления подобными конструкциями, так как они могут засорять текст запроса и сбивать с толку при чтении кода другими людьми.
Интересный, но спорный метод заключается в оборачивании блоков условий в конструкцию ВЫБОР. Проанализируем пример такого кода:
ГДЕ ВЫБОР
КОГДА ИСТИНА ТОГДА УСЛОВИЕ11 И УСЛОВИЕ12
КОНЕЦ
И ВЫБОР
КОГДА ИСТИНА ТОГДА УСЛОВИЕ21 И УСЛОВИЕ22
КОНЕЦ
Важное предупреждение: Хотя это значительно улучшает визуальную структуру, использование ВЫБОР в блоке ГДЕ может быть крайне опасным для производительности. С точки зрения SQL-сервера, такие выражения часто являются «не-SARGable» (Search Argumentable). Это означает, что оптимизатор базы данных может отказаться от использования индексов и перейдет к полному сканированию таблицы (Table Scan). Если в вашей таблице миллионы строк, такой "красивый" запрос может выполняться в десятки раз медленнее обычного.
Более продвинутый способ — замена абстрактной ИСТИНА на параметры с говорящими названиями. Это помогает не только сгруппировать условия, но и задокументировать их смысл. Посмотрим на реализацию:
ГДЕ &ЭтоБлокФильтровПоСкладу
И (Склад = &Склад И Склад.Тип = &ТипСклада)
И &ЭтоБлокФильтровПоНоменклатуре
И (Номенклатура В (&СписокНоменклатуры) И НЕ Номенклатура.Услуга)
В коде 1С перед выполнением запроса вам нужно будет просто установить эти параметры в значение Истина. Это отличный способ для этапа отладки. Позже, когда запрос будет окончательно отлажен, эти параметры можно заменить на обычные комментарии, если вы готовы к тому, что Конструктор запроса может их удалить.
Рассмотрим стандартный способ группировки — использование круглых скобок. Проблема в том, что если скобки не меняют приоритет операций (например, вы используете только оператор И), Конструктор запроса считает их избыточными и удаляет при закрытии визуального редактора.
Чтобы сохранить группировку, разработчики часто идут на хитрость: добавляют внутрь скобок условие, которое заставляет конструктор сохранить структуру, или используют скобки только там, где логика действительно требует разделения И и ИЛИ. Выясним причину такого поведения: конструктор стремится к каноническому виду запроса, оптимизируя его текст для парсера платформы.
Если условий действительно много, лучшим решением с точки зрения и читабельности, и производительности будет разделение запроса на несколько этапов с использованием временных таблиц. Разберем этот процесс по шагам:
ВТ_БазовыеДанные.ВТ_БазовыеДанные и накладываем специфические условия (например, по свойствам товаров или остаткам). Результат — во временную таблицу ВТ_ОтфильтрованныеДанные.Такой подход делает структуру запроса прозрачной. При отладке в Консоли запросов вы сможете посмотреть содержимое каждой временной таблицы и понять, на каком этапе "отваливаются" нужные записи.
Для самых сложных случаев, когда запрос должен строиться динамически в зависимости от множества условий, рекомендуется использовать объект СхемаЗапроса. Этот программный интерфейс позволяет работать с запросом как с объектом, добавляя условия в коллекцию Отбор программно.
Проанализируем преимущества этого метода:
И и ГДЕ.Выбирая способ группировки, всегда соблюдайте баланс между красотой кода и скоростью его работы. Мы рекомендуем придерживаться следующих правил:
ВЫБОР и сложных функций в блоке ГДЕ, чтобы не блокировать работу индексов SQL-сервера.СхемаЗапроса, которая избавит вас от манипуляций со строками.