【问题标题】:How can I optimize this SQL query with nested SELECT's?如何使用嵌套 SELECT 优化此 SQL 查询?
【发布时间】:2025-11-25 17:20:03
【问题描述】:

我有以下疑问:

SELECT src_big, created, modified, owner, aid, caption 
FROM photo 
WHERE aid IN (SELECT aid, modified FROM album WHERE owner IN (SELECT uid2 FROM friend WHERE uid1=me() or uid2 = me())order by modified desc) 
ORDER BY created DESC 
LIMIT 30

这运行起来很慢,我敢肯定是因为嵌套的 SELECT 等。我怎样才能让它执行得更快?应该如何重写才能更好的优化?

【问题讨论】:

    标签: mysql sql database select


    【解决方案1】:

    尝试使用连接而不是 SubQuery 更快:

    SELECT photo.src_big, photo.created, photo.modified, photo.owner, photo.aid, 
    photo.caption FROM photo 
    inner join album on album.aid = photo.aid 
    inner join  friend on album.owner = friend.uid2 
    WHERE uid1=me() or uid2 = me()
    order by modified desc,created DESC LIMIT 30
    

    注意:你需要把表名放在最后

    【讨论】:

    • 我唯一的表是专辑和朋友,对吗?我应该怎么把它们放在最后?
    【解决方案2】:

    我们的 Facebook 游戏中有几个实例需要这种功能,但我们遇到了很多问题。在 mySQL 中,似乎外部查询的每一行都会重新运行嵌套查询,这将重新运行嵌套在其中的查询,从而使其非常慢。我们发现将内部查询的结果返回给 php,将其连接起来,然后使用编译后的列表运行下一个查询非常快。不确定是否有一个完全在 mySQL 内部的解决方案,但这个解决方案对我们来说非常有效。

    另一个潜在的问题可能是索引,您需要确保您搜索或排序的所有列都被正确索引。在查询中使用 mySQLs Explain 函数也有助于发现问题。

    【讨论】:

      【解决方案3】:

      你可以让它成为一个连接

      select (stuff) from photo join album
      on photo.aid = album.aid join friend
      on album.owner = friend.uid2 
      where friend.uid1 = me() or friend.uid2 = me()
      order by created desc limit 30
      

      但请注意:因为您使用的是存储函数,所以它永远不会进入查询缓存。

      您可以通过在查询前加上“desc”来查看查询发生了什么 - 这将向您展示优化器是如何处理它的。

      【讨论】: