39

当查询中没有进行聚合时,为什么有人会使用 group by 而不是 distinct?

此外,是否有人通过 MySQL 和 SQL Server 中的不同性能考虑来了解该组。我猜 SQL Server 有一个更好的优化器,它们可能在那儿接近同等水平,但在 MySQL 中,我预计会有明显的性能优势。

我对dba的答案很感兴趣。

编辑:

比尔的帖子很有趣,但不适用。让我更具体...

select a, b, c 
from table x
group by a, b,c

相对

select distinct a,b,c
from table x
4

5 回答 5

29

GROUP BY将行组映射到一行,每个特定列中的不同值,甚至不一定必须在选择列表中。

SELECT b, c, d FROM table1 GROUP BY a;

该查询是合法的 SQL(更正:仅在 MySQL 中;实际上它不是标准 SQL,其他品牌不支持)。MySQL 接受它,并且它相信您知道自己在做什么,选择bc和以明确的d方式,因为它们a.

但是,Microsoft SQL Server 等品牌不允许这种查询,因为它不能轻易确定函数依赖关系。 编辑:相反,标准 SQL 要求您遵循Single-Value Rule,即选择列表中的每一列都必须在GROUP BY子句中命名,或者是集合函数的参数。

DISTINCT总是查看选择列表中的所有列,并且只查看那些列。这是一个常见的误解,DISTINCT允许您指定列:

SELECT DISTINCT(a), b, c FROM table1;

尽管括号DISTINCT看起来像函数调用,但事实并非如此。这是一个查询选项,选择列表的三个字段中的任何一个字段中的不同值都将导致查询结果中的不同行。此选择列表中的表达式之一有括号,但这不会影响结果。

于 2009-01-09T02:48:44.607 回答
18

来自 MS SQL Server 的一点(非常少)经验数据,来自我们数据库的几个随机表。

对于模式:

SELECT col1, col2 FROM table GROUP BY col1, col2

SELECT DISTINCT col1, col2 FROM table 

当查询没有覆盖索引时,两种方式都会产生以下查询计划:

|--Sort(DISTINCT ORDER BY:([table].[col1] ASC, [table].[col2] ASC))
   |--Clustered Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index]))

当有一个覆盖指数时,两者都产生:

|--Stream Aggregate(GROUP BY:([table].[col1], [table].[col2]))
   |--Index Scan(OBJECT:([db].[dbo].[table].[IX_some_index]), ORDERED FORWARD)

因此,从那个非常小的示例中,SQL Server 肯定将两者视为相同。

于 2009-01-09T04:22:40.050 回答
3

在 MySQL 中,我发现使用 GROUP BY 在性能上通常比 DISTINCT 更好。

执行“EXPLAIN SELECT DISTINCT”会显示“Using where; Using temporary” MySQL 将创建一个临时表。

vs a "EXPLAIN SELECT a,b, c from T1, T2 where T2.A=T1.A GROUP BY a" 只显示"Using where"

于 2011-06-30T11:13:15.450 回答
2

两者都会在 MS SQL Server 中生成相同的查询计划......如果你有 MS SQL Server,你可以启用实际的执行计划来查看哪个更适合你的需求......

请看一下这些帖子:

http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/

http://www.sqlmag.com/Article/ArticleID/24282/sql_server_24282.html

于 2009-01-09T01:42:08.813 回答
0

如果您真的在寻找不同的值,则不同的值会使源代码更具可读性(就像它是存储过程的一部分)如果我正在编写临时查询,我通常会从 group by 开始,即使我有没有聚合,因为我最终会经常把它们放在上面。

于 2009-01-09T03:27:48.147 回答