繁体   English   中英

在循环中运行SQL count(*)查询或尝试将其合并到父查询中是否更快?

[英]Is it faster to run an SQL count(*) query in a loop, or try to merge it into the parent query?

我有一个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)将它们合并在一起可能会使代码的可读性降低。 那么什么是最佳实践? 两个可读查询还是一个难以理解但快速的查询?

除非您发布表架构,否则我们不知道哪个会运行得更快。 如果您是我,我可能会运行查询1,收集所有shift_id然后再运行1个查询,使用INshift_id列表的计数。

这样的事情。

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`

在这种情况下,纯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)这两个查询可以合并在一起吗? 合并后的代码是什么样的?

以下查询可能适合您:

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)那么什么是最佳实践? 两个可读查询还是一个难以理解但快速的查询?

一般规则是“在性能出现问题之前,可读性才是重点”。 仅仅因为计算资源比人力资源便宜

如果您想要的只是第二条SQL产生的计数,那么它将更具可读性,并且会更短。

SELECT COUNT(*) numrows
FROM shifts
Where shift_id = 42 
   and race_id = '17'
   and shift_deleted = 0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM