使用INNER JOIN或EXISTS来查找属于m2m关系的几个更好吗?

Rom*_*mko 15 mysql sql performance many-to-many

给定m2m关系:items-categories我有三个表:

  • 物品,
  • 类别
  • 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 ...
Run Code Online (Sandbox Code Playgroud)

我可以通过两种方式在mySQL中实现这一点.

选项A:内部联合:

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
...;
Run Code Online (Sandbox Code Playgroud)

方案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
...;
Run Code Online (Sandbox Code Playgroud)

两种选择都有效.问题是:哪个是大项目表最快/最优?或者是否缺少OPTION CI?

Joe*_*eph 12

选项A.

JOIN具有优势EXIST,因为它将更有效地使用索引,特别是在大型表的情况下


dan*_*111 11

JOIN一般来说,A 更有效.

但是,需要注意的一点是,连接可以在输出中产生重复的行.例如,如果item id在类别1和3中,则第一个JOIN将导致id为123的两行.如果item id 999在类别1,3,7,8,12和66中,则将获得8行for结果中有999(2*2*2).

重复的行是您需要注意和处理的东西.在这种情况下,你可以使用select distinct id....但是,通过复杂的查询,消除重复可能会变得更加复杂.

  • 我正在使用内部连接转换“exists”。我现在需要消除重复的结果,所以我尝试使用不同的或分组依据。在我的例子中,性能差异要糟糕得多 (2认同)