考虑下面的简单声明,我在客户表中使用SUM和COUNT值,但我也想使用这些值来计算第三列average_sale。
我立即尝试使用“看起来”更清晰的列别名但是我不得不再次使用SUM和COUNT。
这是表现好吗?
SELECT
SUM(payments.amount) as total_sales,
COUNT(payments.id) as quantity,
SUM(payments.amount) / COUNT(payments.id) as average_sale,
`users`.`name`,
`payments`.`user_id`
FROM `payments`
INNER JOIN `users` on `payments`.`user_id` = `users`.`id`
GROUP BY `payments`.`user_id`
ORDER BY `total_sales` DESC
作为一般答案我会说,不。但是,只有SQL执行计划才能说明。
在您的情况下,您将多次重复使用相同的聚合表达式。即使是基本的SQL优化器也应该意识到它们是相同的,并且会一次计算每个优化器。
由于您的查询没有过滤条件,因此它将整个读取两个表。查询的最大成本可能与连接顺序有关。它应该从payments
开始然后走到users
,反之亦然?索引的存在/消除在这里是决定性的。
编辑:
现在,如果您发现优化器不那么聪明,您可以确保它只使用子查询(如果使用MySQL 8.x,则为CTE)计算每个聚合一次。例如,您可以将查询重新表述为:
select
total_sales,
quantity,
total_sales / quantity as average_sale,
`name`,
`user_id`
from (
SELECT
SUM(payments.amount) as total_sales,
COUNT(payments.id) as quantity,
`users`.`name`,
`payments`.`user_id`
FROM `payments`
INNER JOIN `users` on `payments`.`user_id` = `users`.`id`
GROUP BY `payments`.`user_id`
) x
ORDER BY `total_sales` DESC