如何优化此查询以防止超时

时间:2019-10-27 15:20:21

标签: mysql sql

从下面具有架构的数据库

movieActor (actorID, movieID)
rental (rentalID, inventoryID, customerID)
inventory (inventoryID, movieID)

我正在尝试列出一对从同一演员租借电影的客户。结果集应由三列组成

customerID1,customerID2,nOfCommonActors

例如

23 44 5 
11 44 3

其中第一行表示ID为23和44的客户分别租借了各种电影,但在这两组电影中都扮演过的演员中有5个客户出租了电影23和44

我想出了这个查询,但是它要花很多时间运行,并且超时而没有返回任何结果。想知道如何提高效率(我正在使用MYSQL):

SELECT r1.customerID AS customerID1,
    r2.customerID AS customerID2,
    COUNT(DISTINCT fa.actorID) as nOfCommonActors
FROM movieActor AS fa
    JOIN (SELECT r.customerID, i.movieID, fa.actorID
    FROM rental AS r
        JOIN inventory i
        ON i.inventoryID=r.inventoryID
        JOIN movieActor AS fa
        ON fa.actorID=i.movieID
) AS r1
    JOIN (SELECT r.customerID, i.movieID, fa.actorID
    FROM rental AS r
        JOIN inventory i
        ON i.inventoryID=r.inventoryID
        JOIN movieActor AS fa
        ON fa.actorID=i.movieID
) AS r2
    ON r2.actorID=r1.actorID
        AND r1.customerID < r2.customerID 
GROUP BY r1.customerID, r2.customerID
ORDER BY nOfCommonActors DESC;

2 个答案:

答案 0 :(得分:1)

我能想到的一件事是子查询中的select distinct

SELECT ca.customerID AS customerID1,
       ca2.customerID AS customerID2,
       COUNT(*) as nOfCommonActors
FROM (SELECT DISTINCT r.customerID, fa.actorID
      FROM rental r JOIN
           inventory i
           ON i.inventoryID = r.inventoryID JOIN
           movieActor fa
           ON fa.actorID = i.movieID
     ) ca JOIN
     (SELECT DISTINCT r.customerID, fa.actorID
      FROM rental r JOIN
           inventory i
           ON i.inventoryID = r.inventoryID JOIN
           movieActor fa
           ON fa.actorID = i.movieID
    ) ca2
    ON ca.actorID = ca2.actorID AND
        ca.customerID < ca2.customerID
GROUP BY ca.customerID, ca2.customerID
ORDER BY nOfCommonActors DESC;

您的版本正在大大增加子查询中的行数。这会使JOIN变得更加昂贵-而且所有多余的工作都变得一无所有,因为您仍然想COUNT(DISTINCT)

答案 1 :(得分:0)

将查询拆分为sectoin,以便统计信息绘制最佳路径

SELECT DISTINCT r.customerID,fa.actorID 进入#t1       从出租r JOIN            库存我            ON i.inventoryID = r.inventoryID加入            movieActor fa            开启fa.actorID = i.movi​​eID

SELECT DISTINCT r.customerID,fa.actorID 进入#t1       从出租r JOIN            库存我            ON i.inventoryID = r.inventoryID加入            movieActor fa            开启fa.actorID = i.movi​​eID

选择#t1.customerID AS customerID1,        #t2.customerID AS客户ID2,        COUNT(*)作为nOfCommonActors 从         (         选择#t1.customerID,#t2.customerID         从#t1         加入#t2 ON#t1.actorID =#t2.actorID和#t1.customerID <#t2.customerID)

按#t1.customerID,#t2.customerID分组 通过nOfCommonActors DESC进行订购;