Is it better to use INNER JOIN or EXISTS to find belonging to several in m2m relation?
给定的对象-关系M2M:在桌子有三类:
- 项目
- 鸭类
- _类的项目,两个队都证明人
我想找个项目属于给定类:全套
1 2 3 4 5 |
有两种方式,我觉得在这两个accomplish MySQL。
选项A:内部连接:
1 2 3 4 5 6 7 8 9 10 |
选项B:exists:
1 2 3 4 5 6 | 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 ...; |
两个期权的工作。问题是:"这是fastest最佳/最大的表项呢?或是有一个选项C am missing?
一般来说,
但是,要注意的一点是,联接可以在输出中生成重复的行。例如,如果项目ID在类别1和类别3中,则第一个
重复行是您需要注意和处理的内容。在这种情况下,您只需使用
方案A
与
您在选项A中使用联接,在选项B中使用子查询。区别在于:
在大多数情况下,联接比子查询更快,而且子查询更快是非常罕见的。
在joins中,RDBMS可以创建一个更适合查询的执行计划,可以预测应该加载哪些数据以进行处理并节省时间,而不像子查询那样,它将运行所有查询并加载所有数据以进行处理。
子查询的好处在于,它们比联接更可读:这就是大多数新的SQL用户更喜欢它们的原因;这是一种简单的方法;但在性能方面,联接在大多数情况下都更好,即使它们并不难读取。
1 2 3 4 5 6 7 8 9 10 11 12 13 | select distinct `user_posts_id` from `user_posts_boxes` where `user_id` = 5 and exists (select * from `box` where `user_posts_boxes`.`box_id` = `box`.`id` and `status` in ("A","F")) order by `user_posts_id` desc limit 200; select distinct `user_posts_id` from `user_posts_boxes` INNER JOIN box on box.id = `user_posts_boxes`.`box_id` and box.`status` in ("A","F") and box.user_id = 5 order by `user_posts_id` desc limit 200 |
我尝试了这两个查询,但上面的查询对我来说更快。两个表都有大的数据集。几乎"用户邮箱"有400万个,邮箱150万个。
第一次查询时间=0.147 ms第二次查询几乎=0.5到0.9毫秒
但是我的数据库表是inno db,并且也应用了物理关系。
所以我应该选择exists,但它也取决于你如何拥有你的db结构。