SQL: Как понять, когда надо писать условие в JOIN-условие, а когда в WHERE

Это в общем-то важно только для LEFT JOIN, для INNER JOIN тут могут быть только теоретические различия в производительности, хотя думаю, что парсер их решит.

Допустим у нас есть сотрудники, оборудование и таблица связи между ними.

Для простоты убрал внешние ключи и лишние столбцы.

Если нам нужно вывести оборудование, которое ещё ни разу никому не выдавалось, то нам нужен запрос:

Если нам нужен полный список оборудования, но при этом для оборудования «на руках» нужно выводить дату, когда оно было выдано, и сотрудника, которому оно было выдано:

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

То есть первый запрос ограничивает всю выборку (поэтому условие пишется в WHERE), а второй запрос ограничивает «участие LEFTJOINed таблицы» в выборке, поэтому условие пишется в условии ON.

2 Responses so far.

  1. тесты :?

    если я не ошибаюсь то с условием в JOIN мы создаем временную таблицу?
    проверьте на большом объеме данных

    • bullgare:
      Нет, вы неправы.
      Создания временной таблицы можно избежать, простроив правильно индексы на таблицах для выборки (к примеру).
      На использование временной таблицы можно наткнуться даже при выборке из одной таблицы (попробуйте сделать WHERE по одному полю и GROUP BY или ORDER BY по другому полю).
      Также создание временной таблицы не зависит от объёма данных. При большом объёме данных временная таблица будет создана на диске, что существенно замедлит запрос.
      Будет ли создана временная таблица, можно узнать по полю extra у EXPLAIN (там будет написано using temporary). Где она будет создана — узнать из EXPLAIN нельзя, к сожалению.
      Не надо при этом считать, кстати, что using filesort говорит о том, что временная таблица будет создана на диске, вот маленькая статья на этот счёт — http://www.mysqlperformanceblog.com/2009/03/05/what-does-using-filesort-mean-in-mysql/

LEAVE A COMMENT