MySQL - 使用一个查询的结果在另一个查询中使用

The*_*ver 5 mysql sql database

假设我有这个,产生50,000行:

SELECT photoID FROM photoSearch WHERE photoID BETWEEN 1 AND 50000;
Run Code Online (Sandbox Code Playgroud)

我打算对刚刚返回的那些photoID运行此查询.

SELECT COUNT(people) AS totalPeople, people
FROM people
INNER JOIN photopeople ON photoPeople.peopleID = people.PeopleID
WHERE photoid IN ('ID's from results')
GROUP BY people
ORDER BY totalPeople DESC
Run Code Online (Sandbox Code Playgroud)

但我从其他人和资源中了解到,IN子句表现不佳,特别是因为我可以拥有100,000多个photoID.

将topID中的photoID存储在另一个表(resultsTbl)中或者是一个非常长的字符串中是一个好主意吗?如果是,或者使用连接或子选择来查询这些ID(在底部查询中),而不是使用IN?或者......还有另一种方法可以保持绩效吗?

我们将非常感激地提供任何帮助.

vol*_*ron 14

  1. 将topID中的photoID存储在另一个表(resultsTbl)中或者是一个非常长的字符串中是一个好主意吗?

    • 在另一张表中:一般来说,没有.如果有很多ID并且您在其他地方执行顶级查询,那么将其存储在缓存表中可能没问题.虽然,对于这种情况,"最高查询"很可能会保留在内存中,因此您应该使用子选择.

    • 在一个很长的字符串中:否.字符串操作通常是高度CPU密集型的.

  2. 如果是,或者使用连接或子选择来查询这些ID(在底部查询中),而不是使用IN?

    • 而不是将其存储在临时表中,只需要开始JOIN(参见下面的示例).在某些情况下,数据库将为IN(select * from foo)您加入.

  • 使用IN(subselect):

    SELECT     count(people) AS totalPeople
             , people
    FROM       people
    INNER JOIN photopeople ON photoPeople.peopleID = people.PeopleID
    WHERE      photoid IN (select  photoID 
                           from    photoSearch 
                           where   photoID 
                           between 1 AND 50000)
    GROUP BY   people
    ORDER BY   totalPeople DESC
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用JOIN

    SELECT     count(people) AS totalPeople
             , people
    FROM       people
    INNER JOIN photopeople ON photoPeople.peopleID = people.PeopleID
    INNER JOIN photoSearch ON photopeople.photoid  = photoSearch.photoID
    WHERE      photoID between 1 AND 50000
    GROUP BY   people
    ORDER BY   totalPeople DESC
    
    Run Code Online (Sandbox Code Playgroud)

  • 尼斯.你可以添加`EXISTS`版本. (3认同)