Подтвердить что ты не робот

Лучше ли использовать INNER JOIN или EXISTS, чтобы найти принадлежность к нескольким отношениям m2m?

Учитывая отношение m2m: элементы-категории У меня есть три таблицы:

  • элементы,
  • категории и
  • items_categories, которые содержат ссылки на

Я хочу найти элемент из всех заданных категорий:

Find Item 
belonging to a category in [1,3,6] 
and belonging to a category in [7,8,4] 
and belonging to a category in [12,66,42]
and ...

Есть два способа, которые я могу придумать для выполнения этого в mySQL.

ВАРИАНТ A: INNER JOIN:

SELECT id from items 
INNER JOIN category c1 ON (item.id = c1.item_id)
INNER JOIN category c2 ON (item.id = c2.item_id)
INNER JOIN category c3 ON (item.id = c3.item_id)
...
WHERE
c1.category_id IN [1,3,6] AND
c2.category_id IN [7,8,4] AND
c3.category_id IN [12,66,42] AND
...;

ВАРИАНТ B: СУЩЕСТВУЕТ:

SELECT id from items
WHERE
EXISTS(SELECT category_id FROM category WHERE category.item_id = id AND category_id in [1,3,6] AND
EXISTS(SELECT category_id FROM category WHERE category.item_id = id AND category_id in [7,8,4] AND
EXISTS(SELECT category_id FROM category WHERE category.item_id = id AND category_id in [12,66,42] AND
...;

Оба варианта работают. Вопрос: Какой самый быстрый/самый оптимальный для большой таблицы элементов? Или есть ОПЦИЯ C Я не хватает?

4b9b3361

Ответ 1

ВАРИАНТ A

JOIN имеет преимущество перед EXIST, поскольку оно будет более эффективно использовать индексы, особенно в случае больших таблиц

Ответ 2

A JOIN более эффективен, вообще говоря.

Однако, одна вещь, о которой нужно знать, состоит в том, что объединения могут создавать повторяющиеся строки в вашем выпуске. Например, если идентификатор элемента находился в категориях 1 и 3, первый JOIN привел бы к двум строкам для id 123. Если идентификатор объекта 999 был в категориях 1,3,7,8,12 и 66, вы бы получили восемь строк для 999 в ваших результатах (2 * 2 * 2).

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

Ответ 3

Вы используете Join вариант A и subquery в Вариант B, Разница заключается в следующем:

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

В JOINs РСУБД может создать план выполнения, который лучше для вашего запроса, и может предсказать, какие данные должны быть загружены для обработки, и сэкономить время, в отличие от подзапроса, где он будет запускать все запросы и загружать все свои данные в выполните обработку.

Хорошая вещь в подзапросах заключается в том, что они более читабельны, чем JOINs: почему большинство новых пользователей SQL предпочитают их; это простой способ; но когда дело доходит до производительности, JOINS лучше в большинстве случаев, хотя их тоже трудно читать.