我的查询类似于:
Select
tradesmen.id,
(SELECT COUNT(quotes.id) FROM quotes WHERE quotes.tradesman_id = tradesmen.id) AS quoted
From
tradesmen;
所以基本上数据库中的每一行都有一个子查询(50,000+)。 现在每个商人可能会有大约1,000到2,000个报价。
所以我可以使用这个子查询来计算它们。
或者,
我可以进行查询以获得所有商人。
select tradesman.id from tradesmen;
执行一次查询以获取所有引号计数
select tradesman_id as id, count(quotes.id) as quotes from quotes group by tradesman_id;
然后遍历每个商人并从数组中拉出每个商人的计数。
mysql的速度有多快?第二种方法会提供显着的好处,还是两种方法都可以接受?
一般参考我的实际查询是:
SELECT
tradesmen.*,
regions.name AS region_name,
GROUP_CONCAT(ptypes_tradesmen.ptype_id SEPARATOR '|') AS ptype_ids,
(SELECT
COUNT(quotes.id)
FROM
quotes
WHERE
quotes.tradesman_id = tradesmen.id
) AS quoted,
(SELECT
COUNT(quote_intentions.id)
FROM
quote_intentions
WHERE
quote_intentions.tradesman_id = tradesmen.id
) AS intended,
(SELECT
COUNT(quotes.id) FROM quotes
WHERE
quotes.tradesman_id = tradesmen.id
AND quotes.accepted = 1
) AS awarded
FROM
(`tradesmen`)
LEFT JOIN `regions` ON `regions`.`id` = `tradesmen`.`region_id`
LEFT JOIN `ptypes_tradesmen` ON `ptypes_tradesmen`.`tradesman_id` = `tradesmen`.`id`
GROUP BY `tradesmen`.`id`
使用ctrahey的答案我改变了查询。
所以,我们现在有三个版本的查询..
ctraheys:
SELECT
tradesmen.*,
regions.name AS region_name,
GROUP_CONCAT(ptypes_tradesmen.ptype_id SEPARATOR '|') AS ptype_ids,
COUNT(quotes.id) AS quoted,
COUNT(quote_intentions.id) AS intended,
COUNT(NULLIF(quotes.accepted, 0)) AS awarded
FROM (`tradesmen`)
LEFT JOIN `regions` ON `regions`.`id` = `tradesmen`.`region_id`
LEFT JOIN `ptypes_tradesmen` ON `ptypes_tradesmen`.`tradesman_id` = `tradesmen`.`id`
LEFT JOIN quotes ON quotes.tradesman_id = tradesmen.id
LEFT JOIN quote_intentions ON quote_intentions.tradesman_id = tradesmen.id
GROUP BY `tradesmen`.`id`
我的修改版本:
SELECT
t.*,
r.name AS region_name,
GROUP_CONCAT(p.ptype_id SEPARATOR "|") AS ptype_ids,
COUNT(q.id) as quoted,
COUNT(i.id) as intended,
COUNT(NULLIF(q.accepted, 0)) as awarded
FROM (tradesmen t)
LEFT JOIN regions r ON r.id = t.region_id
LEFT JOIN quotes q ON t.id = q.tradesman_id
LEFT JOIN quote_intentions i ON t.id = i.tradesman_id
LEFT JOIN ptypes_tradesmen p ON p.tradesman_id = t.id
GROUP BY t.id
原文:
SELECT
tradesmen.*,
regions.name AS region_name,
GROUP_CONCAT(ptypes_tradesmen.ptype_id SEPARATOR '|') AS ptype_ids,
(SELECT
COUNT(quotes.id)
FROM
quotes
WHERE
quotes.tradesman_id = tradesmen.id
) AS quoted,
(SELECT
COUNT(quote_intentions.id)
FROM
quote_intentions
WHERE
quote_intentions.tradesman_id = tradesmen.id
) AS intended,
(SELECT
COUNT(quotes.id) FROM quotes
WHERE
quotes.tradesman_id = tradesmen.id
AND quotes.accepted = 1
) AS awarded
FROM
(`tradesmen`)
LEFT JOIN `regions` ON `regions`.`id` = `tradesmen`.`region_id`
LEFT JOIN `ptypes_tradesmen` ON `ptypes_tradesmen`.`tradesman_id` = `tradesmen`.`id`
GROUP BY `tradesmen`.`id`
虽然它们都返回了几乎相同的结果,但最后四个字段存在差异(因此我将从结果数组中删除所有其他行)。
从原始查询(正确结果):
array('id' => '53',
'ptype_ids' => '58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68',
'quoted' => '6',
'intended' => '14',
'awarded' => '3'),
来自ctrahey的查询:
array('id' => '53',
'ptype_ids' => '58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|58|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|7|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|17|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|40|40|40|40|40|4',
'quoted' => '2016',
'intended' => '2016',
'awarded' => '1008'),
来自我修改过的查询:
array('id' => '53',
'ptype_ids' => '58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46|13|67|8|75|59|23|9|31|71|24|68|58|2|7|17|1|40|52|4|74|66|19|15|46',
'quoted' => '2016',
'intended' => '2016',
'awarded' => '1008'),
答案 0 :(得分:5)
既不!做一个正确的JOIN(RDBMS中的实际值是):
SELECT
tradesmen.id,
COUNT(quotes.id) as quoted
FROM
tradesmen
LEFT JOIN quotes ON quotes.tradesman_id = tradesmen.id
GROUP BY tradesmen.id
此查询将正是您所需要的并且快速闪电!
真实查询中唯一需要注意的是接受引号计数中的NULLIF位,因为(IIRC)COUNT()将计数false / 0,但不是NULL。
SELECT
tradesmen.*,
regions.name AS region_name,
GROUP_CONCAT(ptypes_tradesmen.ptype_id SEPARATOR '|') AS ptype_ids,
COUNT(quotes.id) AS quoted
COUNT(quote_intentions.id) AS intended
COUNT(NULLIF(quotes.accepted, 0)) AS awarded
FROM (`tradesmen`)
LEFT JOIN `regions` ON `regions`.`id` = `tradesmen`.`region_id`
LEFT JOIN `ptypes_tradesmen` ON `ptypes_tradesmen`.`tradesman_id` = `tradesmen`.`id`
LEFT JOIN quotes ON quotes.tradesman_id = tradesmen.id
LEFT JOIN quote_intentions ON quote_intentions.tradesman_id = tradesmen.id
GROUP BY `tradesmen`.`id`