为什么对于相同的ID,相同的MySQL查询需要花费更长的时间?

时间:2019-07-17 00:51:00

标签: mysql performance join time

这是我用来获取和显示个人资料页面数据的查询。每个类别都有自己的表,因为用户不断将它们添加到表中。我是MYSQL的新手,必须做错什么,因为一个提供者(id = 56)的查询花费0.7秒,而id = 164的提供者的查询花费27秒(!!!)。我以为他们绑定的数据量差不多,所以我不知道为什么要花这么长时间。

由于我是MySQL的新手,所以我不知道我的长查询是否正常,或者是否有更短,更简单的方法(我没有意识到)。但是,它对我所有的提供商(除了一家)来说都很好。

我对两者都做了一个解释,唯一的区别是慢查询中列出的“类型”有4个“全部”,而快查询中的“类型”只有2个,对于表示“额外”的列相同-慢查询有4个,上面写着“使用位置;使用连接缓冲区(块嵌套循环)”,而快查询有2个。我不确定它们是什么意思,但这就是我要弄清楚的。

感谢您的帮助!

更改/删除Concat和Distinct并没有帮助。

SELECT `providers`.`id`,
`providers`.`provider_first_name`, 
`providers`.`provider_last_name`,
`providers`.`p_date_added`,
`degrees`.`degree_type`,
GROUP_CONCAT(DISTINCT `degrees`.`degree_type` SEPARATOR ', ') AS 
all_degrees,
`specialties`.`specialty`,
GROUP_CONCAT(DISTINCT `specialties`.`specialty` SEPARATOR ', ') AS 
all_specialties,
`locations`.`city`, `locations`.`state`,
GROUP_CONCAT(DISTINCT CONCAT(`locations`.`city`, ', ', 
`locations`.`state`)
ORDER BY `locations`.`city`
SEPARATOR '<br>'
) AS all_locations,
`practices`.`practice_name`,
GROUP_CONCAT(DISTINCT `practices`.`practice_name` SEPARATOR '<br>') 
AS all_practices,
`links`.`link`,
GROUP_CONCAT(DISTINCT `links`.`link` SEPARATOR '<br>') AS 
all_links,
`conditions`.`condition_name`,
GROUP_CONCAT(DISTINCT `conditions`.`condition_name` SEPARATOR ', ') 
AS all_conditions,
`reviews`.`review`, `reviews`.`star_rating`, 
`reviews`.`r_date_added`,
AVG(`reviews`.`star_rating`) AS rating
FROM `providers`
LEFT JOIN `degrees` ON `providers`.`id` = `degrees`.`prov_id`
LEFT JOIN `specialties` ON `providers`.`id` = 
`specialties`.`prov_id`
LEFT JOIN `locations` ON `providers`.`id` = `locations`.`prov_id`
LEFT JOIN `practices` ON `providers`.`id` = `practices`.`prov_id`
LEFT JOIN `links` ON `providers`.`id` = `links`.`prov_id`
LEFT JOIN `conditions` ON `providers`.`id` = `conditions`.`prov_id`
LEFT JOIN `reviews` ON `providers`.`id` = `reviews`.`prov_id`
WHERE `id`= {$providerid}
GROUP BY `id`

2 个答案:

答案 0 :(得分:0)

EXPLAIN query

ALL 表示它等同于对表进行完全扫描。为了防止这种情况,请在表上添加索引。在通常用于搜索或连接某些数据的列上添加索引。

ROWS 表示索引记录中记录的基数。数字越小越好。

https://dev.mysql.com/doc/refman/5.7/en/explain-output.html

阅读有关EXPLAIN的更多信息确实有帮助。

答案 1 :(得分:0)

爆炸式爆炸-JOINs爆炸行数,然后GROUP BY爆炸到很少(显然只有一个)。

为避免这种情况,请将LEFT JOINs移到SELECT中。例如:

SELECT ...
       GROUP_CONCAT(DISTINCT `degrees`.`degree_type` SEPARATOR ', ') AS all_degrees,
    ...
    LEFT JOIN  `degrees`  ON `providers`.`id` = `degrees`.`prov_id`
    ...

->

SELECT ...
        ( SELECT GROUP_CONCAT(DISTINCT `degree_type` SEPARATOR ', ')
              FROM `degrees`
              WHERE `providers`.`id` = `prov_id`
        ) AS all_degrees,
     ...

最后的GROUP BY id可以删除。

在这一点上,DISTINCT可能是多余的;尝试删除它。