代码之家  ›  专栏  ›  技术社区  ›  vava

在MySQL中选择DISTINCT或GroupBy更快些什么?

  •  244
  • vava  · 技术社区  · 15 年前

    CREATE TABLE users (
      id int(10) unsigned NOT NULL auto_increment,
      name varchar(255) NOT NULL,
      profession varchar(255) NOT NULL,
      employer varchar(255) NOT NULL,
      PRIMARY KEY  (id)
    )
    

    我想得到所有的 profession 字段中,什么更快(或推荐):

    SELECT DISTINCT u.profession FROM users u
    

    SELECT u.profession FROM users u GROUP BY u.profession
    

    ?

    15 回复  |  直到 7 年前
        1
  •  277
  •   guest    10 年前

    它们本质上是等价的(事实上,有些数据库就是这样实现的) DISTINCT

    如果其中一个跑得更快,它会 不同的 . 这是因为,尽管两者相同,但查询优化器必须捕获以下事实: GROUP BY 不利用任何组成员,只利用他们的密钥。 不同的 使其显式化,因此您可以使用稍微愚蠢的优化器。

    如果有疑问,请测试!

        2
  •  106
  •   Quassnoi    15 年前

    如果你有一个索引 profession

    如果没有,则使用 DISTINCT .

    GROUP BY 在里面 MySQL 对结果进行排序。你甚至可以:

    SELECT u.profession FROM users u GROUP BY u.profession DESC
    

    把你的职业分类 DESC

    不同的 创建临时表并使用它存储重复项。 分组 执行相同的操作,但随后会对不同的结果进行分类。

    SELECT DISTINCT u.profession FROM users u
    

    .

        3
  •  23
  •   daniel.gindi    11 年前

    对于单列上的DISTINCT与单列上的GROUP BY的情况,上述所有答案都是正确的。

    但是,如果您在查询中选择了多个列,则DISTINCT本质上是不同的!因为在本例中,它将比较所有行的所有列,而不仅仅是一列。

    因此,如果您有类似以下内容:

    // This will NOT return unique by [id], but unique by (id,name)
    SELECT DISTINCT id, name FROM some_query_with_joins
    
    // This will select unique by [id].
    SELECT id, name FROM some_query_with_joins GROUP BY id
    

    认为DISTINCT关键字通过指定的第一列来区分行是一个常见错误,但DISTINCT是一个通用关键字。

    因此,人们你必须小心,不要认为上面的答案在所有情况下都是正确的。。。你可能会感到困惑,并得到错误的结果,而所有你想要的是优化!

        4
  •  17
  •   Raj    12 年前

    尽可能选择最简单和最短的答案——DISTINCT似乎更符合您的要求,因为它将为您提供您所需要的答案,而且仅此而已!

        5
  •  8
  •   Pavel Stehule    11 年前

    在postgres中,well distinct有时比group by慢(不知道其他数据库)。

    测试示例:

    postgres=# select count(*) from (select distinct i from g) a;
    
    count 
    
    10001
    (1 row)
    
    Time: 1563,109 ms
    
    postgres=# select count(*) from (select i from g group by i) a;
    
    count
    10001
    (1 row)
    
    Time: 594,481 ms
    

    http://www.pgsql.cz/index.php/PostgreSQL_SQL_Tricks_I

    所以要小心…:)

        6
  •  7
  •   TheTechGuy    11 年前

    Group by比Distinct昂贵,因为Group by对结果进行排序,而Distinct避免排序。但是如果你想让分组产生与distinct相同的结果,就给它一个例子 按空排序 ..

    SELECT DISTINCT u.profession FROM users u
    

    等于

    SELECT u.profession FROM users u GROUP BY u.profession order by null
    
        7
  •  5
  •   amartynov    15 年前

    比较:

    1. 描述从northwind.products中选择不同的产品名称
    2. 描述按产品名称从northwind.products组中选择产品名称

    第二个查询额外提供了“usingfilesort”。

        8
  •  3
  •   Ahmed Ekri    11 年前

    MySQL , " Group By filesort . 我意识到 DISTINCT GROUP BY ,这是一个惊喜。

        9
  •  3
  •   Grumpy    9 年前

    经过大量测试,我们得出结论,分组比分组更快

    opnamegroep_实习生 从…起 telwerken 哪里 opnemergroep opnamegroep_实习生在(7,8,9,10,11,12,13)组

    总计635秒0.0944秒

    选择sql\u no\u缓存 独特(opnamegroep_实习生) 从…起 特尔维肯 哪里 opnemergroep 在(7,8,9,10,11,12,13)中

    总共635秒,0.2117秒(几乎慢100%) 韦尔盖夫货车记录0-29条(总计635条,查询duurde 0.3468秒)

        10
  •  2
  •   Ivan Dossev    12 年前

    在某些情况下,您必须使用GROUP BY,例如,如果您想获得每个雇主的员工人数:

    SELECT u.employer, COUNT(u.id) AS "total employees" FROM users u GROUP BY u.employer
    

    在这种情况下 DISTINCT u.employer 不正常。也许有办法,但我就是不知道。(如果有人知道如何使用DISTINCT进行此类查询,请添加注释!)

        11
  •  2
  •   Aung Myo Linn    8 年前

    DECLARE @t1 DATETIME;
    DECLARE @t2 DATETIME;
    
    SET @t1 = GETDATE();
    SELECT DISTINCT u.profession FROM users u; --Query with DISTINCT
    SET @t2 = GETDATE();
    PRINT 'Elapsed time (ms): ' + CAST(DATEDIFF(millisecond, @t1, @t2) AS varchar);
    
    SET @t1 = GETDATE();
    SELECT u.profession FROM users u GROUP BY u.profession; --Query with GROUP BY
    SET @t2 = GETDATE();
    PRINT 'Elapsed time (ms): ' + CAST(DATEDIFF(millisecond, @t1, @t2) AS varchar);
    

    或尝试 SET STATISTICS TIME (Transact-SQL)

    SET STATISTICS TIME ON;
    SELECT DISTINCT u.profession FROM users u; --Query with DISTINCT
    SELECT u.profession FROM users u GROUP BY u.profession; --Query with GROUP BY
    SET STATISTICS TIME OFF;
    

    它只显示解析、编译和执行每条语句所需的毫秒数,如下所示:

     SQL Server Execution Times:
       CPU time = 0 ms,  elapsed time = 2 ms.
    
        12
  •  1
  •   user2832991    9 年前

    这不是规则

    对于每个查询。。。。请分别尝试,然后按…分组。。。比较完成每个查询的时间并使用更快的。。。。

    在我的项目中,有时我使用group by和其他不同的方法

        13
  •  0
  •   tehvan    15 年前

    如果您不必执行任何组函数(sum、average等,以防向表中添加数字数据),请使用SELECT DISTINCT。我怀疑它更快,但我没有什么可以证明的。

    在任何情况下,如果担心速度,请在列上创建索引。

        14
  •  0
  •   Beep beep    15 年前

    SELECT DISTINCT始终与GROUP BY相同或更快。在某些系统(如Oracle)上,它可能会被优化为与大多数查询的DISTINCT相同。在其他服务器(如SQL Server)上,速度可能会快得多。

        15
  •  0
  •   Daniel R    10 年前

    如果 这个问题允许它,try-with-EXISTS,因为它被优化为在找到结果时立即结束(并且不缓冲任何响应),所以,如果您只是尝试规范化像这样的WHERE子句的数据

    SELECT FROM SOMETHING S WHERE S.ID IN ( SELECT DISTINCT DCR.SOMETHING_ID FROM DIFF_CARDINALITY_RELATIONSHIP DCR ) -- to keep same cardinality
    

    SELECT FROM SOMETHING S WHERE EXISTS ( SELECT 1 FROM DIFF_CARDINALITY_RELATIONSHIP DCR WHERE DCR.SOMETHING_ID = S.ID )
    

        16
  •  0
  •   da Bich    3 年前

    在mySQL中,我发现GROUPBY会将NULL视为distinct,而distinct不会。

    所以我倾向于相信mySQL中有更多的独特之处。