1

以下是伪查询,所以我不关心结果,但是以下 MySQL 查询之间是否存在任何差异(在性能、结果数量等方面)?

查询 1

SELECT u.`username`, COUNT(*) AS 'posts', u.`age`
FROM `users` u
INNER JOIN `posts` p
ON p.`user_id`=u.`id`
GROUP BY u.`id`
HAVING u.`age` > 12

假设smth这个查询中的列只是为了HAVING条件而被选择的,所以结果中不需要它的值。

查询 2

SELECT u.`username`, COUNT(*) AS 'posts'
FROM `users` u
INNER JOIN `posts` p
ON p.`user_id`=u.`id` AND u.`age` > 12
GROUP BY u.`id`
4

2 回答 2

2

HAVING 总是在所有 JOIN 和 WHERE 过滤器完成后完成。它本质上是查询结果的过滤器。这就是为什么您不能使用它来过滤不属于查询的字段的原因。

您的查询会以不同的方式执行。查询 2 会更有效,因为它会在 JOIN 期间过滤掉用户。查询 1 将加入所有用户,提取所有数据并将其分组,然后按年龄过滤。查询 2 将仅对 12 岁以下的用户进行 GROUP 和过滤,然后对其进行 GROUP。在查询 2 中需要读取和分组的数据更少。

于 2012-09-24T03:23:24.713 回答
1

您的查询完全不同。特别是,第二个是有效的标准 SQL 语法。第一个使用 MySQL 功能,允许在聚合中允许任何列。

特别是,smth第一个查询中的列来自匹配数据中的任意行。如果所有行上的所有值都相同,则两者的结果将是等效的。

如果我假设 u.id 对于用户中的每一行都是唯一的,那么结果集是等效的。但是,我认为更易读的 SQL 版本是:

SELECT u.`username`, COUNT(*) AS 'posts', u.`smth`
FROM `users` u  INNER JOIN
     `posts` p 
     ON p.`user_id`=u.`id`
WHERE u.smth is not null
GROUP BY u.`id`, u.username
HAVING u.`smth` IS NOT NULL 

这清楚地表明您希望在每一行上都有一个单独的用户名,并且您不希望 smth 为 NULL。在性能方面,这个版本都相当于你的第二个版本,三个应该差不多。

于 2012-09-24T03:05:26.023 回答