Выберите первое изображение из нескольких изображений с помощью JOIN mysql - PullRequest
0 голосов
/ 18 ноября 2018

У меня есть три таблицы food, fav_food и food_image. Таблица food содержит подробную информацию о продуктах, food_image содержит несколько изображений для одного продукта и fav_food таблица имеет идентификаторы любимой еды пользователя.

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). Итак, мой вопрос: как написать более быстрый запрос для достижения моей цели?

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

Это ситуация, когда коррелированный подзапрос должен иметь лучшую производительность:

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 необходимо обработать все данные в таблице изображений.Это нужно только для обработки любимых продуктов для данного пользователя.

Наконец, ROW_NUMBER() - это опция в MySQL 8+.Тем не менее, это все еще может быть быстрее или быстрее, чем это решение (основываясь на моем опыте работы с другими базами данных).

0 голосов
/ 18 ноября 2018

Рассмотрите возможность объединения трех таблиц, а затем используйте оконную функцию, например 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...