使用表中的子查询来缓慢MySQL查询

时间:2013-03-01 10:07:07

标签: mysql database subquery

我试图根据IF语句返回一个字符串,但速度非常慢。

它与第一个子查询有关,但我不确定如何重新排列,以便更快地恢复相同的结果。

这是我的SQL:

SELECT IF
(
    (
        SELECT COUNT(*)
        FROM 
            (
                SELECT DISTINCT enquiryId, type 
                FROM parts_enquiries, parts_service_types AS pst 
                WHERE parts_enquiries.serviceTypeId = pst.id
            ) AS parts
        WHERE parts.enquiryId = enquiries.id
    ) > 1, 'Mixed',
    (
        SELECT DISTINCT type 
        FROM parts_enquiries, parts_service_types AS pst 
        WHERE parts_enquiries.serviceTypeId = pst.id AND enquiryId = enquiries.id
    )
) AS partTypes
FROM  enquiries,
entities
WHERE enquiries.entityId = entities.id

如何让它更快?


我在下面修改了原始查询,但是我收到子查询返回多行的错误:

SELECT
(SELECT
   CASE WHEN COUNT(DISTINCT type) > 1 THEN 'Mixed' ELSE `type` END AS type
FROM parts_enquiries 
INNER JOIN parts_service_types AS pst ON parts_enquiries.serviceTypeId = pst.id
INNER JOIN enquiries ON parts_enquiries.enquiryId = enquiries.id
INNER JOIN entities ON enquiries.entityId = entities.id
GROUP BY enquiryId) AS partTypes
FROM  enquiries,
entities
WHERE enquiries.entityId = entities.id

EXPLAIN result

2 个答案:

答案 0 :(得分:1)

请查看此查询是否产生相同的结果:

SELECT 
   enquiryId, 
   CASE WHEN COUNT(DISTINCT type) > 1 THEN 'Mixed' ELSE `type` END AS type
FROM parts_enquiries 
INNER JOIN parts_service_types AS pst ON parts_enquiries.serviceTypeId = pst.id
INNER JOIN enquiries ON parts_enquiries.enquiryId = enquiries.id
INNER JOIN entities ON enquiries.entityId = entities.id
GROUP BY enquiryId

但N.B.的评论仍然有效。要查看是否使用了索引以及我们需要查看EXPLAIN和表定义的其他信息。

答案 1 :(得分:0)

这可以让你得到你想要的东西。

我首先预先查询您的零件查询和零件服务类型,查找零件“类型”的计数和MINIMUM,按查询ID分组。

然后,针对该结果运行您的IF()。如果不同的计数是> 0,然后'混合'。如果只有一个,因为我做了MIN(),它只会有你想要的那个值的描述。

SELECT
      E.ID
      IF ( PreQuery.DistTypes > 1, 'Mixed', PreQuery.FirstType ) as PartType
   from 
      Enquiries E
         JOIN ( SELECT
                      PE.EnquiryID,
                      COUNT( DISTINCT PE.ServiceTypeID ) as DistTypes,
                      MIN( PST.Type ) as FirstType
                   from 
                      Parts_Enquiries PE
                         JOIN Parts_Service_Types PST
                            ON PE.ServiceTypeID = PST.ID
                   group by 
                      PE.EnquiryID ) as PreQuery
            ON E.ID = PreQuery.EnquiryID