Какой подход будет быстрее?

Я должен выбрать список пользователей, и для каждого из них я должен вернуть информацию о том, за кем он следит или нет (текущий / запрашивающий пользователь). Сейчас я запрашиваю так:

SELECT 
   "User"."name", 
   EXISTS(
      SELECT * FROM "Followings" f WHERE f."FollowedId" = "User"."id" AND f."FollowerId" = 123
   )::boolean AS "isFollowed"
FROM "Users" AS "User" 
ORDER BY "User"."createdAt" 
LIMIT 15

Примечание: 123 - это идентификатор пользователя, который получает список пользователей.

Является ли id хорошей идеей для создания такого вложенного SELECT? Какова производительность такого запроса?

Моя вторая идея просто сделать "Users" LEFT JOIN "Followings" - если присоединяется следующее, то следует пользователь. Какой из подходов будет лучше?

1 ответ

Решение

Да, ваш запрос об оптимальном. Я просто упростил и удалил лишнее приведение:

SELECT name
     , EXISTS (
          SELECT 1 FROM "Followings" f
          WHERE  f."FollowedId" = u."id"
          AND    f."FollowerId" = 123
          ) AS "isFollowed"
FROM  "Users" u
ORDER  BY "createdAt" 
LIMIT  15;
  • Актерский состав ::boolean был излишним, так как EXISTS уже возвращает boolean,

Альтернативная форма с LEFT JOIN будет работать примерно так же или медленнее, но будет более сложным и также зависит от ("FollowedId", "FollowerId") быть уникальным, или вы можете получить несколько строк, которые могут испортить LIMITтак что вам нужно будет добавить GROUP BY, Предполагая уникальные пары:

SELECT u.name
     ,(f."FollowedId" IS NOT NULL) AS "isFollowed"
FROM  "Users" u
LEFT  JOIN "Followings" f ON f."FollowedId" = u."id"
                         AND f."FollowerId" = 123
ORDER  BY u."createdAt" 
LIMIT  15;
Другие вопросы по тегам