【发布时间】:2018-11-01 17:37:24
【问题描述】:
我们正在尝试从数据库中获取关注者的最新 10 条通知。我们会进行一些连接,以确保我们为关注者获得正确的通知集。如果他们关注的人(他们的领导者)添加了新帖子,则关注者应该只收到在他们开始关注领导者之后添加的帖子的通知(将他们的领导者的旧帖子显示为新通知是没有意义的)。另一个加入是确保我们获得通知的read_at 时间,以便关注者知道它是否已被阅读。这是查询,但它需要 ~9 秒,这太慢了。理想情况下,它应该只需要几毫秒,特别是索引:
查询:
SELECT nf.id, nf.uuid, nf.leader_id, nf.data, nf.created_at, nfr.read_at
FROM notification_followers nf
LEFT 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
索引:
ALTER TABLE `notification_followers` ADD INDEX `nf_lid_ca_id_idx` (`leader_id`,`created_at`,`id`);
ALTER TABLE `user_follows` ADD KEY`uf_fid_lid_fs_ca_idx` (`follower_id`,`leader_id`,`follow_status`,`created_at`)
ALTER TABLE `notification_followers_read` ADD INDEX `nfr_fid_nfid_ra_idx` (`follower_id`,`notification_followers_id`,`read_at`);
说明:
正确的结果(大约需要 9 秒):
SQL 转储:
SQL DUMP TO REPRODUCE LOCALLY 只需在本地创建 speed_test 数据库并导入文件即可查看所有表数据的慢查询问题(~100K 行)。
我们如何优化上述内容以在几毫秒内得到正确的结果?
【问题讨论】:
-
这是一个内连接,对吧?
-
不确定,但使用当前
LEFT JOIN返回正确结果 -
在通知被读取或始终可用后,notification_followers_id 是否存在于 notification_followers_read 表中?
-
读完之后。
标签: mysql sql select left-join innodb