Какой подход будет быстрее?
Я должен выбрать список пользователей, и для каждого из них я должен вернуть информацию о том, за кем он следит или нет (текущий / запрашивающий пользователь). Сейчас я запрашиваю так:
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;