如果有人帮我弄清楚以下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
答案 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
,这可以提高性能。