我有三个表food
,fav_food
和food_image
。 food
表包含有关食物的详细信息,food_image
具有针对单个食物的多个图像,并且
fav_food
表具有用户喜欢的食物ID。
food:
f_id | description
food_image
f_id | img_url | rank
fav_food
user_id | f_id
这是我尝试过的:
SELECT food.f_id,
food.description,
img.minimgrank,
i.img_url AS profile_photo
FROM fav_food
INNER JOIN food
ON fav_food.f_id = food.f_id
LEFT OUTER JOIN(SELECT f_id,
Min(rank) AS minImgRank
FROM food_image
GROUP BY f_id) img
ON img.f_id = food.f_id
JOIN food_image i
ON i.rank = img.minimgrank
WHERE fav_food.user_id = ?
现在,我需要一个查询,该查询将以描述和图像显示用户最喜欢的食物。尽管有多张图像,但我需要选择一个具有最小等级的图像(假设等级为1,2,3
,将选择等级为1
的图像)。所以我的问题是如何编写更快的查询以实现我的目标?
答案 0 :(得分:1)
考虑联接三个表,然后再使用诸如min(rank)
之类的窗口函数来获取结果。
select *
from (
select a.user_id
,b.img_url
,b.rank
,min(b.rank) over(order by b.rank asc) as rnk
from fav_food a
join food_image b
on a.f_id=b.f_id
join food c
on a.f_id=c.f_id
)x
where x.rank=x.rnk
答案 1 :(得分:0)
在这种情况下,相关子查询应具有更好的性能:
SELECT f.f_id, f.description,
fi.rank, fi.img_url AS profile_photo
FROM fav_food ff JOIN
food f
ON ff.f_id = f.f_id LEFT JOIN
food_image fi
ON fi.f_id = f.f_id AND
fi.rank = (SELECT MIN(fi2.rank) FROM food_image fi2 WHERE fi2.f_id = fi.f_id)
WHERE ff.user_id = ? ;
为了提高性能,您要确保在food_image(f_id, rank)
和fav_food(user_id, f_id)
上都有索引,并在主键上都有索引。
为什么它比GROUP BY
版本更快?首先,索引可以用于相关查询,但可能不会用于JOIN
之后的GROUP BY
。
第二,GROUP BY
需要处理图像表中的所有数据。只需处理给定用户喜欢的食物即可。
最后,在MySQL 8+中,ROW_NUMBER()
是一个选项。但是,这仍然可能比该解决方案快或快(根据我对其他数据库的经验)。