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

Mysql 在循环中运行SQL count(*)查询更快,还是尝试将其合并到父查询中更快?,mysql,sql,performance,optimization,count,Mysql,Sql,Performance,Optimization,Count,我有一个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 SELECT COUNT(*) AS `numro

我有一个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
SELECT COUNT(*) AS `numrows`
FROM `volunteer_shifts`
WHERE `shift_id` = 'Y'
AND `shift_deleted` =0
该查询从数据库中提取志愿者轮班列表。然后我有一个PHP循环,对于上面查询中的每个移位,它都运行这个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
SELECT COUNT(*) AS `numrows`
FROM `volunteer_shifts`
WHERE `shift_id` = 'Y'
AND `shift_deleted` =0
因此,如果第一个查询中有5个班次,那么第二个查询将运行5次,每个班次运行一次

1) 这两个查询可以合并在一起吗?组合的代码是什么样子的

2) 合并这两个查询是否更快


3) 将它们合并在一起可能会降低代码的可读性。那么什么是最佳实践呢?两个可读的查询或一个难读但快速的查询?

在这种情况下,纯SQL将比应用层(即PHP)的循环更易于维护、可读和高效。因此,考虑将聚合查询作为派生表(通知SefftTyID现在是一个分组)。现在,计数将与一个查询中的其他字段一起显示:

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

在这种情况下,纯SQL将比应用层(即PHP)的循环更易于维护、可读和高效。因此,考虑将聚合查询作为派生表(通知SefftTyID现在是一个分组)。现在,计数将与一个查询中的其他字段一起显示:

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

除非发布表架构,否则我们不知道哪一个运行得更快。 如果我是你,我可能会运行查询1,收集所有的
shift\u id
s,然后再运行一个查询,使用
中的
提取
shift\u 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`

除非发布表架构,否则我们不知道哪一个运行得更快。 如果我是你,我可能会运行查询1,收集所有的
shift\u id
s,然后再运行一个查询,使用
中的
提取
shift\u 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生成的计数,那么它将更具可读性,并且会更短

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

如果您只需要第二个SQL生成的计数,那么它将更具可读性,并且会更短

SELECT COUNT(*) numrows
FROM shifts
Where shift_id = 42 
   and race_id = '17'
   and shift_deleted = 0
2) 合并这两个查询是否更快

单次查询速度肯定会更快,因为没有时间花在网络活动上(想象一下数据库位于另一台服务器上,这是非常常见的情况)

另外,独立查询方法不允许内置DB查询优化器执行其工作

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

一般规则是“在性能出现问题之前,可读性是主要的”。只是因为计算资源比人力资源便宜

2) 合并这两个查询是否更快

单次查询速度肯定会更快,因为没有时间花在网络活动上(想象一下数据库位于另一台服务器上,这是非常常见的情况)

另外,独立查询方法不允许内置DB查询优化器执行其工作

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


一般规则是“在性能出现问题之前,可读性是主要的”。只是因为计算机资源比人力资源便宜

我编辑了我的问题,让它更清楚。第二个查询位于第一个查询结果的循环中。我需要第一个查询中每个结果的计数(*)。我编辑了我的问题以使其更清楚。第二个查询位于第一个查询结果的循环中。我需要对第一个查询中的每个结果进行计数(*)。没有测量,“更快”是没有意义的。它快10毫秒吗?还是一小时?没有测量,你无法做出真正的决定。没有测量,“更快”是毫无意义的。它快10毫秒吗?还是一小时?没有测量,你无法做出真正的决定。谢谢你的回答。这似乎是将两个查询合并在一起的最简单方法。今天晚些时候,我可能会将此标记为最佳答案。您认为在SELECT语句中添加更多子查询会更好地提高性能和代码性能吗?如果重构另一组查询,我可能会在SELECT语句中得到7个子查询。所有查询都具有COUNT(*)或SUM()性质,不能用作内部联接。提前感谢您的反馈。@AdmiralAdama在大多数情况下,我更愿意使用子查询/分组感谢您的回答。这似乎是将两个查询合并在一起的最简单方法。今天晚些时候,我可能会将此标记为最佳答案。您认为在SELECT语句中添加更多子查询会更好的性能和代码明智吗?如果重构另一组查询,我可能会在SELECT语句中得到7个子查询。所有查询都具有COUNT(*)或SUM()性质,不能用作内部联接。提前感谢您的反馈。@AdmiralAdama在大多数情况下,我更喜欢使用子查询/分组