在连接表上排序真的很慢

问题描述 投票:0回答:1

我有一个与 job_events 表左连接的 jobs 表。 job_events 表有一个关于 type 和 jobId 的索引。

当我按 jobs.id 订购查询时,结果会在 200 毫秒内显示。当我通过 job_events.created_at 订购时,需要 1.74 秒。

如何改进此查询,使其运行时间低于 1 秒。

这是 SQL 查询

SELECT *
FROM jobs
LEFT JOIN job_events ON job_events.jobId = jobs.id
    AND job_events.id = (
        SELECT MAX(id) FROM job_events 
        WHERE jobId = jobs.id
    )
LEFT JOIN job_events created_by_events ON created_by_events.jobId = jobs.id
    AND created_by_events.type = 'Created By'
    AND created_by_events.id = (
        SELECT MAX(id) FROM job_events 
        WHERE jobId = jobs.id AND type = created_by_events.type
    )
LEFT JOIN job_events completed_job_events ON completed_job_events.jobId = jobs.id
    AND completed_job_events.type IN ('Job Completed', 'Job Complete')
    AND completed_job_events.id = (
        SELECT MAX(id) FROM job_events 
        WHERE jobId = jobs.id AND type = completed_job_events.type
    )
WHERE status IN (5, 6)
ORDER BY job_events.created_at
LIMIT 101;

Mysql详解:

sql mysql query-optimization
1个回答
0
投票

当按

jobs.id
排序时,服务器只需要评估连接,直到有足够的行来满足限制子句。当按
job_events.created_at
排序时,它必须评估每个
jobs
行的连接。

您没有包含 DDL 或任何有关数据分布的信息,因此这有点盲目。

您可以将三个单独聚合的计算移至子查询并使用条件聚合:

SELECT *
FROM (
    SELECT j.*,
        MAX(je.id) AS max_id,
        MAX(IF(je.type = 'Created By', je.id, NULL)) AS max_created_by_id,
        MAX(IF(je.type IN ('Job Completed', 'Job Complete'), je.id, NULL)) AS max_completed_id
    FROM jobs j
    LEFT JOIN job_events je ON j.id = je.jobId
    WHERE j.status IN (5, 6)
    GROUP BY j.id
) AS temp
LEFT JOIN job_events je1 ON je1.id = temp.max_id
LEFT JOIN job_events je2 ON je2.id = temp.max_created_by_id
LEFT JOIN job_events je3 ON je3.id = temp.max_completed_id
ORDER BY je1.created_at ASC
LIMIT 101;
© www.soinside.com 2019 - 2024. All rights reserved.