我正在运行一个基本的标记式系统,我想知道我的查询效率如何。
我的具体使用案例涉及使用recipe
通过ingredients
对象标记requirement
个对象,该对象具有recipe_id
和ingredient_id
。
食谱,成分和要求都完全由user
孤立。
我希望能够返回用户的食谱,其中包含给定集合中的所有成分。
我这样做的方式,给出ingredient_ids
(1,2)和user_id
1 的列表,就像这样:
SELECT `recipes`.* FROM `recipes`
WHERE `recipes`.`id` IN (
SELECT `requirements`.`recipe_id`
FROM `requirements`
WHERE `requirements`.`ingredient_id` IN (1, 2)
AND `requirements`.`user_id` = 1
GROUP BY `requirements`.`recipe_id`
HAVING COUNT(`requirements`.`recipe_id`) = 2)
这是返回我需要的数据,但我担心它的性能。子查询看起来不太好,因为它使用ingredient_id 1或2抓取所有需求,按配方对它们进行分组,然后将它们计数以匹配给定的数组大小,只需创建一个数组,以进一步查询配方ID。 / p>
但是requirements
表可能是庞大的,因为每个条目管理食谱和成分之间可能存在n个平方的双向关系。因此,以这种方式查询整个表是没有意义的。
我错过了什么吗?
我经常听说IN和NULL相等比较比JOIN快得多,但当子查询的复杂性否定了速度节省时肯定不会这样做吗?
这似乎是一个非常简单的问题,我过度工程,你会如何改进它?
答案 0 :(得分:0)
我没有你的数据库进行测试,抱歉,所以我不确定这是否会产生你想要的结果。但也许尝试加入requirements
表而不是使用子查询,它将避免潜在的性能损失,并且只需要通常更清晰的代码。以下是我希望对您有用的信息:
SELECT `recipes`.`recipe_id`
FROM `recipes` AS rec
JOIN `requirements` AS req ON rec.`recipe_id` = req.`recipe_id`
WHERE `requirements`.`ingredient_id` IN (1, 2)
AND `requirements`.`user_id` = 1
GROUP BY `recipes`.`recipe_id`
HAVING COUNT(`requirements`.`ingredient_id`) = 2
如果您有任何疑问,请告诉我