我正在尝试优化这个mysql查询

我正在尝试优化这个mysql查询,mysql,Mysql,对于这个愚蠢的问题,我已经超过12秒了 SELECT * FROM notifications WHERE `to` IN (SELECT following FROM followers WHERE follower = 3) LIMIT 0,20 知道问题出在哪里吗?我应该使用联接吗?首先,添加以下“覆盖”,多列索引: followers(follower, following) SELECT n.name, n.notification FROM followers f JOIN no

对于这个愚蠢的问题,我已经超过12秒了

SELECT *
FROM notifications
WHERE `to` IN (SELECT following FROM followers WHERE follower = 3)
LIMIT 0,20
知道问题出在哪里吗?我应该使用联接吗?

首先,添加以下“覆盖”,多列索引:

followers(follower, following)
SELECT n.name, n.notification
FROM followers f
JOIN notifications n
  ON n.`to` = f.following
WHERE f.follower = 3
MySQL将能够只运行一次不相关的子查询,但它可能会扫描notifications表中的所有行,并将结果与之进行比较。如果通知中有许多行,则此查询可能会很慢

使用以下格式的
JOIN
,MySQL能够立即将结果集减少到followers表中follower为3的那些行:

SELECT n.*
FROM followers f
JOIN notifications n
  ON n.`to` = f.following
WHERE f.follower = 3
MySQL随后将查找“to”列匹配的每条记录的notifications表。根据您的数据集,这可能比通知的完整表扫描快

对于
连接
,您还需要添加以下索引:

notifications(`to`)
如果可以将结果缩小为几个命名列,则还可以将这些命名列添加到索引中,以创建覆盖多列索引:

followers(follower, following)
SELECT n.name, n.notification
FROM followers f
JOIN notifications n
  ON n.`to` = f.following
WHERE f.follower = 3
然后是这样的覆盖指数:

notifications(`to`, name, notification)

试试
join
版本,看看它是否运行得更快。是的,您应该这样做。尝试使用join并将*替换为列名。如果不需要,可以删除一些列。在
to
和/或
follower
字段上是否有索引?to是mysql保留的关键字,通常会出现错误。可能是mysql内部正在处理它,而且需要很长时间?@PoX:它在后台处理,所以这不是问题。如果不是,查询甚至不会运行。