[ Вопрос дня ] Язык запросов: отличие условий в соединении таблиц от условий в блоке «ГДЕ»

Доброго дня, коллеги!

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

Тренер Мастер-группы курса Разработка и оптимизация запросов в 1С:Предприятие 8 помогает слушателям разобраться в тонкостях работы запросов, используя простые примеры.

Вопрос

В одном из уроков устанавливается условие на тип цен на закладке СВЯЗИ. В чем будет отличие, если сделать это на закладке УСЛОВИЯ? Чем руководствоваться при выборе?

Ответ

Здесь следует руководствоваться порядком выполнения операций. Сначала выполняются связи таблиц, затем отборы из секции ГДЕ.

В данном видеоуроке при соединении таблиц уже необходимо учитывать только цены определенного вида, чтобы цены другого вида вообще не мешали, т.к. нужно получать максимальный период только среди цен определенного вида.

Пример:

Соединяем две таблицы – Товары и Цены. Предположим, в каждой таблице существует только одна запись – есть один товар, на него назначена одна цена.

Первый запрос:

ВЫБРАТЬ
    Товары.Товар КАК Товар,
    Цены.Цена КАК Цена
ИЗ
    Товары КАК Товары
        ЛЕВОЕ СОЕДИНЕНИЕ Цены КАК Цены
        ПО Товары.Товар = Цены.Товар
            И (Цены.ВидЦен = &ВидЦен)

В таком случае в результате запроса получим одну запись, даже если в регистре нет цены нужного вида.

Второй запрос:

ВЫБРАТЬ
    Товары.Товар КАК Товар,
    Цены.Цена КАК Цена
ИЗ
    Товары КАК Товары
        ЛЕВОЕ СОЕДИНЕНИЕ Цены КАК Цены
        ПО Товары.Товар = Цены.Товар
ГДЕ
    Цены.ВидЦен = &ВидЦен

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

Напишите в комментариях, пользуетесь ли Вы возможностью установки отбора при соединении таблиц?

P.S.

Понимать, как работают запросы и уметь их строить - обязательный навык для всех, кто дорабатывает и внедряет 1С.

После курса Вы сможете:

  • Строить сложные запросы с несколькими источниками данных
  • Уверенно задействовать вложенные запросы и временные таблицы
  • Использовать встроенный язык для обработки результатов запроса
  • Учитывать особенности соединений и объединений нескольких таблиц.
  • Разрабатывать запросы на уровне задач Аттестации 1С:Специалист по платформе.
Программа, стоимость, условия и регистрация в группу: «Запросы в 1С 8.3, Базовый курс (с нуля до уровня Специалист по платформе)» Для всех, кто внедряет и дорабатывает 1С.

Комментарии / обсуждение (7):

  1. Максим

    Если смотреть план запросов, то сначала выбираются данные из таблиц, а потом результаты данных соединяются и тут уже применяется один из методов (nested loops, Hash Join, Merge Join).

    Я хочу сказать, 1 запрос, выполнится следующим образом: 1. Сначала будет выбраны данные из провой таблицы с отбором по виду цен и отбором по товару из левой таблицы. 2. Затем будут выбраны все записи из левой таблицы. 3. После чего будет соединение nested loops (left outer join). Для 2 запроса ровным счетом будет все тоже самое, только пункт 3 поменяет соединение nested loops (inner outer join). Резюме такое, что не совсем верно, указывать, что сначала выполняются условия, которые в соединении, а потом условие в секции “ГДЕ”. Сначала все-таки оптимизатор получает данные из таблиц с наложением условий в секции “где” и даже тех условий, которые находятся в связях, а позже объединяет их по условиям в связях.

    • Василий Ханевич

      Добрый день!
      Спасибо за комментарий.
      Здесь в первую очередь мы обращаем внимание на то, что может быть получен разный результат в зависимости от того, расположено условие в предложении ГДЕ или в условии соединения.
      Планы запросов в этом курсе еще не изучали, но нужно объяснить, в чем же заключается разница. Поэтому объясняем с логической точки зрения, ведь и в первом, и во втором запросе используется одно и то же левое соединение, а не внутреннее.
      Похожий подход есть и в документации для MS SQL Server – Логический порядок обработки инструкции SELECT. Также в статье отмечается, что это именно логическое деление, фактическое выполнение может отличаться, что собственно Вы и подмечаете.

  2. Teploukhov

    С вышеуказанным примером все и так ясно. Гораздо интереснее было бы узнать, отличие условий в соединении таблиц от условий в блоке “ГДЕ” при внутреннем соединении. Результат запроса будет ровно таким же. А как та или иная реализация отразится на производительности? Если используется множество таблиц с внутренним соединением, можно ли считать, что создание сложного условия соединения окажется более выигрышным, нежели соединение по простому ключу и использование условия в секции “ГДЕ”?

    • Василий Ханевич

      Добрый день!
      Самый правильный вариант – сравнить оба варианта по производительности, проанализировать планы запросов для конкретной ситуации.
      При этом надо учитывать, что у оптимизатора СУБД есть специальные “приемы” для выполнения соединений (Hash Join или Merge Join), которые могут обеспечить получение данных оптимальным образом.

  3. Кирилл

    Что за странная ситуация когда приводится конкретный пример, но выводы делаются на основании различных ситуаций. При этом делается условие превращающее соединение во внутреннее.

    • Василий Ханевич

      Добрый день!
      Да, Вы правильно написали. Такое левое соединение фактически “превращается” во внутреннее.
      Перемещение условия с закладки Связи в конструкторе запроса на закладку Условия может изменить результат запроса.
      Подобный пример и рассматривается в курсе.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Вход на сайт

Зарегистрироваться

Подтверждение регистрации будет отправлено на указанный e-mail.

Я подтверждаю, что ознакомлен(а) с Пользовательским соглашением, принимаю его условия и даю свое согласие на обработку моих персональных данных.

Восстановить доступ

E-mail или логин

Ссылка на создание нового пароля будет отправлена на указанный e-mail.