将子查询转换为连接以提高性能

时间:2012-10-25 15:09:30

标签: mysql join subquery

我接管了一个大项目,随着数据库变得越来越大,一些代码停止了工作,

以下是查找rendering_requests最后rending_logpending的{​​{1}}的查询,有时会有没有状态更改的日志条目,并记录为noaction我们不需要数数吧。这就是我从查询中理解的内容。

SELECT
    COUNT(rr.rendering_id) AS recordCount
FROM
    rendering_request rr, rendering_log rl
WHERE
    rl.rendering_id = rr.rendering_id 
AND rl.status = 'pending'   AND
    rl.log_id = (
            SELECT rl1.log_id
            FROM rendering_log rl1
            WHERE 
            rl.rendering_id = rl1.rendering_id  AND 
            rl1.status = 'pending' 
            AND rl1.log_id = (
                SELECT rl2.log_id
                FROM rendering_log rl2
                WHERE rl1.rendering_id = rl2.rendering_id AND rl2.status!='noaction'
                ORDER BY rl2.log_id DESC LIMIT 1
                    )
            ORDER BY rl1.log_id DESC
            LIMIT 1
            )

例如

rendering_id=1有多个日志

status=noaction
status=noaction
status=pending

rendering_id=2有多个日志

status=noaction
status=assigned
status=noaction
status=pending

当我们运行此查询时,它应显示count=1,因为只有rendering_id=1是我们想要的记录。

现在这个查询已经停止工作了,它挂起了mysql服务器

1 个答案:

答案 0 :(得分:1)

不是100%肯定我有这个权利,但是这样的事情。认为你仍然需要使用几个子选择但是(取决于MySQL的版本)这样做,JOIN应该快得多

SELECT COUNT(rr.rendering_id) AS recordCount
FROM rendering_request rr
INNER JOIN rendering_log rl
ON rl.rendering_id = rr.rendering_id 
INNER JOIN (SELECT rendering_id, MAX(log_id) FROM rendering_log  WHERE status = 'pending' GROUP BY rendering_id) rl1
ON rl1.rendering_id = rl.rendering_id 
AND rl1.log_id = rl.log_id
INNER JOIN (SELECT rendering_id, MAX(log_id) FROM rendering_log  WHERE status!='noaction' GROUP BY rendering_id) rl2
ON rl2.rendering_id = rl1.rendering_id 
AND rl2.log_id = rl1.log_id
WHERE rl.status = 'pending'