GROUP BY 语句什么会更快

What will be faster for GROUP BY statement

假设我有接下来的两个 SQL 服务器表:

CREATE TABLE Users (
    id INT IDENTITY(1, 1) PRIMARY KEY,
    name VARCHAR(100) NOT NULL
)

CREATE TABLE UserLogins (
   id INT IDENTITY(1, 1) PRIMARY KEY,
   user_id INT REFERENCES Users(id) NOT NULL,
   login VARCHAR(100) NOT NULL
)

而且我需要计算每个用户的用户登录次数。并且查询结果应该包含用户名,例如。 哪个查询会更快:

SELECT MAX(name), count(*)
FROM Users u
    INNER JOIN UserLogins ul ON ul.user_id = u.id
GROUP BY u.id 

或下一个:

SELECT name, count(*)
FROM Users u
    INNER JOIN UserLogins ul ON ul.user_id = u.id
GROUP BY u.name 

因此,我不确定是否最好按具有索引的列进行分组,然后使用 MAXMIN 聚合函数。或者只是按 Users.name 分组,它没有任何索引。

提前致谢!

答案是:两者都不正确。

第二个版本完全错误,因为 name 不是唯一的。第一个版本是正确的,虽然它可能效率不高。


由于 nameid 具有 功能依赖性 ,因此 id 的每个唯一值也定义了 [=11= 的值].按 name 分组是错误的,因为 name 不一定是唯一的。仅按 id 分组意味着您需要聚合 name,如果存在函数依赖性,这将毫无意义。所以你实际上想按 both 列分组:

SELECT
  u.name,
  count(*)
FROM Users u
    INNER JOIN UserLogins ul ON ul.user_id = u.id
GROUP BY
  u.id,
  u.name;

请注意,id实际上不需要选择。

此查询几乎肯定会比单独按 name 分组更快,因为服务器无法推断 name 是唯一的,需要对其进行排序和聚合。

它也可能比按 id 分组更快,尽管这可能取决于优化器是否足够聪明来推断函数依赖性(因此不需要聚合)。即使它不聪明,这也可能不会很慢,因为 id 已经是唯一的,所以扫描 id 上的索引不需要排序,只需要聚合。