在以下查询中哪个部分很昂贵?

时间:2014-07-30 11:34:34

标签: mysql sql joomla

如果有人帮我弄清楚以下SQL查询中最昂贵的部分,我将不胜感激:

SELECT a.*, c.id AS companyid, c.name AS companyname, 
CONCAT_WS(" ",fname,lname) AS name, c.alias as co_alias, 
count(DISTINCT(amprop.prop_id)) AS prop_count
FROM #__iproperty_agents as a
LEFT JOIN #__iproperty_agentmid as amprop ON amprop.agent_id = a.id
LEFT JOIN #__iproperty_companies as c on c.id = a.company
WHERE a.state = 1 AND c.state = 1 AND a.featured = 1
GROUP BY a.id
ORDER BY RAND() 

此查询执行时间超过20秒,这很荒谬。 CMS是joomla 3.15,这是iproperty joomla组件中的查询。

id select_type table  type   possible_keys key                        key_len ref                           rows   Extra
 1 SIMPLE      a      ALL    company       NO INDEX KEY COULD BE USED NULL    NULL                          8      using where; Using temporary; Using tilesort
 1 SIMPLE      c      eq_ref PRIMARY       PRIMARY                    4       daily_dailyrealsnew.a.company 1      using where
 1 SIMPLE      amprop index  agent_id      prop_id                    8       NULL                          229294 Using index

1 个答案:

答案 0 :(得分:0)

这是您的查询:

SELECT a.*, c.id AS companyid, c.name AS companyname, 
       CONCAT_WS(" ",fname,lname) AS name, c.alias as co_alias, 
       count(DISTINCT(amprop.prop_id)) AS prop_count
FROM #__iproperty_agents as a LEFT JOIN
     #__iproperty_agentmid as amprop
     ON amprop.agent_id = a.id LEFT JOIN
     #__iproperty_companies as c
     on c.id = a.company
WHERE a.state = 1 AND c.state = 1 AND a.featured = 1
GROUP BY a.id
ORDER BY RAND() ;

要真正理解它,你需要看一下解释。一些索引会有所帮助。让我假设所有id都是主键,因此有效地编入索引。然后,#__iproperty_agents(state, featured)#__iproperty_companies(state)上的索引可能会有所帮助。

杀戮性能很可能是group by。您可以尝试使用相关子查询。使用正确的索引,这应该表现得非常好:

SELECT a.*, c.id AS companyid, c.name AS companyname, 
       CONCAT_WS(' ', fname, lname) AS name, c.alias as co_alias, 
       (select count(distinct amprop.prop_id)
        from #__iproperty_agentmid amprop
        where amprop.agent_id = a.id
       ) as prop_count
FROM #__iproperty_agents a LEFT JOIN
     #__iproperty_companies c
     on c.id = a.company
WHERE a.state = 1 AND c.state = 1 AND a.featured = 1
ORDER BY RAND() ;

对于此查询,您需要#__iproperty_agentmid(agent_id, prop_id)上的索引。使用相关子查询会删除外部group by,这可以提高性能。

相关问题