子查询显着降低查询速度

时间:2016-12-21 03:35:18

标签: mysql database

我尝试执行一个替换多个查询以生成结果集的查询。我有一个相当直接的1到1个连接集,但是我试图从一个表中获得每个主记录保存多个记录的一列。基本上它是这样的:

带有主键id列和一堆其他列的

meet_entries, meet_entries_statuses,带有autoincrement id列和meet_entry的id列的外键

meet_entries中每行的meet_entry_statuses中可能有多行。在我的查询中,我试图获取与meet_entry主键id相关联的最近添加的(如此最高的id号)行。

这是我的疑问:

(SELECT meet_entry_status_codes.description
FROM meet_entry_statuses, meet_entry_status_codes
WHERE meet_entry_statuses.code = meet_entry_status_codes.id
AND meet_entry_statuses.id = meet_entries.id
ORDER BY meet_entry_statuses.id DESC
LIMIT 1) as status,

添加位:

{{1}}

将查询从.2秒开始,到永不完成。 meet_entries中只有10个匹配的行。 meet_entries_statuses中约有50行适用于meet_entries中的10行,但正如我所说,我试图只为每个meet_entries行获取1行。有关更好的方法的任何建议?

1 个答案:

答案 0 :(得分:1)

我不确定为什么在没有任何加入条件的情况下加入meet_entry_statusesmeet_entry_status_codes。这样做意味着您正在进行交叉连接。因此,如果meet_entries中有N行,并且上面两个表中分别有M行和P行,则最终会生成N x M x P行。

你可以尝试取出两个连接。我在以下重写的查询中将它们标记出来:

SELECT
    meet_entries.id,
    member.firstname,
    member.surname,
    member.gender,
    member.dob,
    clubs.code,
    clubs.clubname,
    meet_entries.meals,
    meet_entries.massages,
    meet_entries.cost,
    meet_entries.cancelled,
    (SELECT 
            meet_entry_status_codes.description
        FROM 
            meet_entry_statuses         as mes
            , meet_entry_status_codes   as mesc
        WHERE 
            meet_entry_statuses.code = meet_entry_status_codes.id
            AND meet_entry_statuses.id = meet_entries.id
        ORDER BY meet_entry_statuses.id DESC
        LIMIT 1
    ) as status,
    COUNT(DISTINCT meet_events_entries.id) as entries
FROM 
    meet_entries                    as me 
    , meet_events_entries           as mee 
    , member                        as m 
    , clubs                         as c 
    , meet_entry_statuses           as mes      -- try taking this out
    , meet_entry_status_codes       as mesc     -- try taking this out
WHERE 
    meet_entries.meet_id = ?
    AND meet_entries.id = meet_events_entries.meet_entry_id
    AND meet_entries.member_id = member.id
    AND meet_entries.club_id = clubs.id
GROUP BY meet_entries.id
;