Доброго дня, коллеги!
Помните, мы уже разбирали вопрос, где наша внимательная слушательница решила самостоятельно исследовать метаданные конфигурации, в результате чего у нее появились интересные вопросы?
Сегодня у нас похожий случай, когда очередной слушатель, изучая курс Разработка и оптимизация запросов в 1С:Предприятие 8.3, разбираясь в синтаксисе языка запросов 1С, обнаружил занятную деталь.
Вопрос
Если необходимо отобрать тип регистратора для записей регистра, то можно воспользоваться несколькими разными вариантами:
● ГДЕ ТИПЗНАЧЕНИЯ(ТоварныеЗапасы.Регистратор) = ТИП(Документ.РасходТовара) ● ГДЕ ТоварныеЗапасы.Регистратор ССЫЛКА Документ.РасходТовара ● ВЫРАЗИТЬ(Продажи.Регистратор КАК Документ.РасходТовара)
А какой из вариантов оптимален с методической точки зрения? Предположительно ВЫРАЗИТЬ исполнится до отбора данных. Так ли это?
Ответ
Можно использовать первые два варианта – оператор ССЫЛКА или функцию ТИПЗНАЧЕНИЯ.
При помощи оператора ВЫРАЗИТЬ можно привести значение только к одному типу:
ВЫРАЗИТЬ Поле КАК Тип
Т.е. сам по себе он не выполняет отбор. Нужно дополнительно в секции ГДЕ установить отбор.
Оператор ССЫЛКА не убирает лишние неявные соединения (это можно проверить при помощи просмотра плана запроса в консоли), а накладывает отбор по типу. А ВЫРАЗИТЬ явно говорит, что поле будет иметь не составной тип, а одну конкретную ссылку, поэтому не будет лишних соединений.
У оператора ССЫЛКА есть особенность.
Пусть используется следующий фрагмент запроса:
&ЦеноваяГруппа ССЫЛКА Справочник.ЦеновыеГруппы
Если в качестве значения параметра ЦеноваяГруппа установить, например, ссылку на справочник «Номенклатура», система выдаст ошибку:
Несовместимые типы “ССЫЛКА”
& ЦеноваяГруппа <<?>>ССЫЛКА Справочник.ЦеновыеГруппы
При работе с реквизитами составного типа тоже может возникать такая же ошибка. Например, документ «РеализацияТоваровУслуг» не входит в составной тип реквизита ДокументОснование документа «Авансовый Отчет». При выполнении запроса будет ошибка:
ВЫБРАТЬ АвансовыйОтчет.ДокументОснование ССЫЛКА Документ.РеализацияТоваровУслуг ИЗ Документ.АвансовыйОтчет КАК АвансовыйОтчет
Причем конструктор запроса даже не будет открываться. ТИПЗНАЧЕНИЯ при этом отработает корректно.
Фирма 1С поясняет это следующим образом:
«Язык запросов выдает эту ошибку, если в типе проверяемого выражения отсутствует ссылка на проверяемую таблицу.»
Вот такую особенность нужно учитывать при разработке запросов.
Кстати, завтра мы вновь вернемся к запросам. Обещаем, будет интересно!
P.S.
Понимать, как работают запросы и уметь их строить - обязательный навык для всех, кто дорабатывает и внедряет 1С.
После курса Вы сможете:
- Строить сложные запросы с несколькими источниками данных
- Уверенно задействовать вложенные запросы и временные таблицы
- Использовать встроенный язык для обработки результатов запроса
- Учитывать особенности соединений и объединений нескольких таблиц.
- Разрабатывать запросы на уровне задач Аттестации 1С:Специалист по платформе.
А что бы провести отбор ещё по нескольким документам?
Добрый день!
Можно вот так:
РасчетыСКлиентами.Период КАК Период,
РасчетыСКлиентами.Регистратор КАК Регистратор
ИЗ
РегистрНакопления.РасчетыСКлиентами КАК РасчетыСКлиентами
ГДЕ
(РасчетыСКлиентами.Регистратор ССЫЛКА Документ.ВводОстатковВзаиморасчетов
ИЛИ РасчетыСКлиентами.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг)
Спасибо огромное!
Добрый день, на ИТС написано “Не следует использовать ИЛИ в секции ГДЕ запроса. Это может привести к тому, что СУБД не сможет использовать индексы таблиц и будет выполнять сканирование, что увеличит время работы запроса и вероятность возникновения блокировок”. К данному случаю это не относится?
Добрый день!
Да, есть такая рекомендация. И запрос из предыдущего комментария можно переписать с использованием двух объединений вместо оператора ИЛИ.
В общем случае нужно проверить, какие планы запросов на уровне СУБД получаются для каждого из запроса. И выбрать из двух запросов тот, который является оптимальным.
ни разу не приходилось в запросах указывать документ, который не входит в составной тип данных.
обычно ССЫЛКА использую, когда надо отсечь ненужные типы данных в составной типе данных (например получить записи из регистра только определЁнного документа, поэтому в секции ГДЕ пишу Регистратор ССЫЛКА Документ.ххххх).
а вот то, что ССЫЛКА не убирает ненужные соединения – это была полезная инфа!