2009-01-09 167 views
37

为什么在查询中没有完成聚合时,有人会使用group而不是distinct?sql group by versus 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 
+1

这是密切相关的,但不是完全一样的问题在于,http://stackoverflow.com/questions/164319/is-there-any-difference-between-group-by-and-distinct – 2009-01-09 02:38:20

+0

很可能是因为他们不知道他们是怎么回事。如果你确定他们知道他们是怎么回事的话,那么我会怀疑在这两者之间处理NULL值的方式是有区别的,但我不能认为是什么。 – 2009-01-09 05:31:02

+0

我认为答案很简单 - 作者不知道独特(这是令人惊讶的,因为我认为他是专业人士)。 – mson 2009-01-09 09:59:10

回答

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当然对待都一样。

2

双方将产生MS SQL Server的同一查询计划....如果你有MS SQL服务器,你可以只允许将实际执行计划,看看哪一个是你需要更好的...

请看看那些帖子:

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

+0

使用group而不是像newb这样的独特气味。没有任何收益的语法有很多。还有 - 你没有任何指标 - 只是从别人的博客传闻。 – mson 2009-01-09 01:48:50

28

GROUP BY行的图组一行,每个不同的价值具体列,甚至不一定要在选择列表中。

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

这个查询是合法的SQL(修正:只在MySQL中,实际上它不是标准的SQL,而不是其他品牌的支持)。 MySQL接受它,并相信您知道自己在做什么,以明确的方式选择bcd,因为它们是functional dependenciesa

但是,Microsoft SQL Server和其他品牌不允许此查询,因为它无法轻松确定功能依赖关系。 编辑:相反,标准SQL要求您遵循单值规则,即选择列表中的每个列必须在GROUP BY子句中命名,否则必须是设置函数的参数。

DISTINCT总是查看选择列表中的所有列,只查看那些列。这是一个普遍的误解,认为DISTINCT允许您指定的列:

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

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

+1

有趣但无关紧要。您正在回答有关在查询中犯错的问题。另外,我认为接受这样的查询并不符合ansi标准。如果有的话,这是一个在MySQL的错误 - 其他主要供应商不支持这个'功能' – mson 2009-01-09 03:11:03

+0

脱离主题,但第二个查询比尔给(SELECT DISTINCT(a)...)是完全有效的ANSI SQL-92。括号实际上是不相关的;你可以做SELECT a,(b),c FROM table1,这是有效的。只是因为它是它看起来像的第一个参数,'a'是一个DISTINCT的参数。 – Cowan 2009-01-09 04:26:45

0

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

3

在MySQL中,我发现使用GROUP BY的性能往往比DISTINCT更好。

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

Vs的 “从T1,T2 EXPLAIN SELECT A,B,C,其中T2.A = T1.A GROUP BY一个” 只是显示 “使用,其中”