对于此查询:
SELECT nf.id, nf.uuid, nf.leader_id, nf.data, nf.created_at, nfr.read_at
FROM notification_followers nf JOIN
user_follows uf
ON uf.leader_id = nf.leader_id AND uf.follower_id = 14 AND
uf.follow_status = 'follow' LEFT JOIN
notification_followers_read nfr
ON nf.id = nfr.notification_followers_id AND nfr.follower_id = 14
WHERE nf.created_at > uf.created_at
ORDER BY nf.id DESC
LIMIT 10;
我建议索引
user_follower(leader_id, follower_id, follow_status, created_at)
和
notification_followers_read(notification_followers_id, follower_id, read_at)
. 索引中列的顺序很重要。
注意我改变了第一个
JOIN
内部连接,因为
WHERE
无论如何从句都会把它变为一个。
嗯,让我们尝试重写查询:
SELECT nf.id, nf.uuid, nf.leader_id, nf.data, nf.created_at,
(SELECT nfr.read_at
FROM notification_followers_read nfr
WHERE nf.id = nfr.notification_followers_id AND nfr.follower_id = 14
) nfr
FROM (SELECT nf.*
FROM notification_followers nf
WHERE EXISTS (SELECT 1
FROM user_follows uf
WHERE uf.leader_id = nf.leader_id AND uf.follower_id = 14 AND
uf.follow_status = 'follow' AND nf.created_at > uf.created_at
)
ORDER BY nf.id DESC
LIMIT 10
) nf;
为此,您需要确保在
notification_followers(id)
也。
根据您的数据,使用此方法内部子查询可能更快:
FROM (SELECT nf.*
FROM user_follows uf JOIN
notification_followers nf
ON uf.leader_id = nf.leader_id AND nf.created_at > uf.created_at
WHERE uf.follower_id = 14 AND uf.follow_status = 'follow'
ORDER BY nf.id DESC
LIMIT 10
) nf
为此,索引是
user_follows(follower_id, follow_status, leader_id, created_at)
和
notification_followers(leader_id, created_at, id)
. 这可能更快。