V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
xiri
V2EX  ›  数据库

数据库查询时使用 group by(不加 order by)后返回的结果默认是按怎样的规则排序的?

  •  
  •   xiri · 2020-01-02 01:16:21 +08:00 · 2876 次点击
    这是一个创建于 1778 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我知道要让输出结果有序加个 order by 就行,但这里不考虑这一点,就是单纯的想知道 group by 后的输出默认是怎么确定顺序的。

    我这里在 oracle 11g 上进行测试,拿它默认的 scott 用户下的 emp 表举例,表中的 EMPNO 是主键。

    不加 group by

    直接使用select empno,ename from emp;,输出结果如下所示(单独取 EMPNO 或单独取 ENAME 输出的顺序都跟这里是一样的,这里把两列同时取出来方便下面的对比)。

         EMPNO ENAME
    ---------- --------------------
          7369 SMITH
          7499 ALLEN
          7521 WARD
          7566 JONES
          7654 MARTIN
          7698 BLAKE
          7782 CLARK
          7788 SCOTT
          7839 KING
          7844 TURNER
          7876 ADAMS
    
         EMPNO ENAME
    ---------- --------------------
          7900 JAMES
          7902 FORD
          7934 MILLER
    

    加 group by

    使用select ename from emp group by ename;(虽然这样 group by 毫无意义),结果如下。很明显顺序改变了,但是没发现任何规律,不是按字母排的,跟主键 EMPNO 也没有关系

    ENAME
    --------------------
    ALLEN
    JONES
    FORD
    CLARK
    MILLER
    SMITH
    WARD
    MARTIN
    SCOTT
    TURNER
    ADAMS
    
    ENAME
    --------------------
    BLAKE
    KING
    JAMES
    

    比较奇怪的一点是,使用select empno from emp group by empno;时的输出又是有序的,是因为结果都是数字?还是因为 EMPNO 是主键?

         EMPNO
    ----------
          7369
          7499
          7521
          7566
          7654
          7698
          7782
          7788
          7839
          7844
          7876
    
         EMPNO
    ----------
          7900
          7902
          7934
    

    搜索过程中看到这样一句话“数据库中的一个重要理论就是表中的记录是没有顺序的。 如果你不在查询中用 ORDER BY 指定顺序,则系统会‘随机’给出顺序”
    可我感觉就算是“随机”也还是要有一个基础规则的吧,毕竟上面的语句每一次查询输出的结果都是一样的。

    也看到有人说默认是按主键排的,但上面的结果很明显不符合,望大佬解答

    4 条回复    2020-01-02 07:14:38 +08:00
    catror
        1
    catror  
       2020-01-02 01:25:43 +08:00 via Android   ❤️ 1
    看看执行计划
    xiri
        2
    xiri  
    OP
       2020-01-02 01:47:41 +08:00
    @catror 在执行计划里找到原因了,谢谢啦
    select empno 那一句实际上执行的是 sort group by,而 select ename 那一句执行的是 hash group by,这应该算是数据库自己的一种优化吧
    msg7086
        3
    msg7086  
       2020-01-02 02:58:24 +08:00
    数字归并应该是直接比数字快,所以 sort 后 group。文本归并的话用哈希表更快,扔进桶里再归并。换你自己写数据库的话最后其实也会写成这样的。

    至于随机结果,主要是指结果不固定顺序。如果数据库高兴,他可以按照硬盘或者内存中存储的顺序来排序,那也是一种归并算法。
    guanhui07
        4
    guanhui07  
       2020-01-02 07:14:38 +08:00
    执行计划
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5830 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 02:54 · PVG 10:54 · LAX 18:54 · JFK 21:54
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.