我有一个SQL查询。
SELECT `shifts`.*, `races`.`race_attrition_rate`
FROM `shifts`
JOIN `races` ON `races`.`race_id` = `shifts`.`race_id`
WHERE `shifts`.`race_id` = 'X'
AND `shift_deleted` =0
ORDER BY `shift_name` ASC, `shift_id` ASC
该查询从数据库中提取志愿者班次列表。然后我有一个PHP循环,对于在上面的查询中提取的每个班次,运行此SQL查询。
SELECT COUNT(*) AS `numrows`
FROM `volunteer_shifts`
WHERE `shift_id` = 'Y'
AND `shift_deleted` =0
因此,如果在第一个查询中拉出5个班次,则第二个查询将运行5次,每次班次一次。
1)这两个查询可以合并在一起吗?组合代码会是什么样的?
2)将这两个查询合并得更快吗?
3)将它们合并在一起可能会使代码的可读性降低。那么最佳做法是什么?两个可读的查询或一个难以阅读但快速查询?
答案 0 :(得分:2)
除非您发布表架构,否则我们不知道哪个会运行得更快。
如果我是你,我可能会运行查询1,收集所有shift_id
,然后再运行1个查询,使用shift_id
提取IN
列表的计数。
像这样的东西。
SELECT COUNT(*) AS `numrows`, `shift_id`
FROM `volunteer_shifts`
WHERE `shift_id` IN ('42','other number', 'more numbers'...)
AND `shift_deleted` =0
GROUP BY `shift_id`
答案 1 :(得分:1)
在这种情况下,纯SQL比在应用程序层(即PHP)上循环更具可维护性,可读性和高效性。因此,请考虑将聚合查询作为派生表加入(通知 shift_id 现在是一个分组)。现在,计数将与一个查询中的其他字段内联:
SELECT s.*, r.`race_attrition_rate`, agg.`numrows`
FROM `shifts` s
JOIN `races` r ON r.`race_id` = s.`race_id`
JOIN (
SELECT `shift_id`, COUNT(*) AS `numrows`
FROM `volunteer_shifts`
WHERE `shift_deleted` = 0
GROUP BY `shift_id`
) AS agg
ON agg.shift_id = s.shift_id
WHERE r.`race_id` = '17'
AND s.`shift_deleted` = 0
ORDER BY s.`shift_name` ASC, s.`shift_id` ASC
答案 2 :(得分:1)
2)将这两个查询合并得更快吗?
单个查询将更快速地定义,因为没有时间花在网络活动上(只是想象数据库位于另一个服务器上,这是很常见的情况)
另外,单独查询方法不允许内置数据库查询优化器完成其工作
1)这两个查询可以合并在一起吗?组合代码会是什么样的?
以下查询可能适合您:
SELECT
`shifts`.*,
`races`.`race_attrition_rate`,
(SELECT
COUNT(*) AS `numrows`
FROM
`volunteer_shifts`
WHERE
`volunteer_shifts`.`shift_id` = `shifts`.`shift_id`
AND
`shift_deleted` = 0) AS `volunteer_shifts`
FROM
`shifts`
JOIN `races` ON `races`.`race_id` = `shifts`.`race_id`
WHERE
`shifts`.`race_id` = 'X'
AND
`shift_deleted` = 0
ORDER BY
`shift_name` ASC, `shift_id` ASC
3)那么最佳做法是什么?两个可读的查询或一个难以阅读但快速查询?
一般规则是"可读性是主要的一点,直到你遇到性能问题"。仅仅因为计算资源比人力资源便宜
答案 3 :(得分:0)
如果您想要的只是第二个SQL生成的计数,那么它将更具可读性,而且会更短。
SELECT COUNT(*) numrows
FROM shifts
Where shift_id = 42
and race_id = '17'
and shift_deleted = 0