0

私は大きなプロジェクトを引き継ぎましたが、データベースが大きくなるにつれて、一部のコードが機能しなくなりました。

これがrendering_requests最後の人を見つけるためのクエリです。カウントする必要がないため、ステータスが変更されずに記録されたログエントリが存在する場合があります。それが私が質問から理解したことです。rending_logpendingnoaction

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サーバーがハングします

4

1 に答える 1

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'
于 2012-10-25T15:40:37.417 に答える