【问题标题】:Does 'Select' always order by primary key?“选择”是否总是按主键排序?
【发布时间】:2010-10-23 21:59:28
【问题描述】:

为各位 DBA 准备的一个基本的简单问题。

当我进行选择时,是否始终保证我的结果将按主键排序,还是应该使用“order by”指定它?

我使用 Oracle 作为我的数据库。

【问题讨论】:

标签: sql database oracle primary-key


【解决方案1】:

不,如果您不使用“order by”,则无法保证任何订购。事实上,您不能保证从一个查询到下一个查询的顺序是相同的。请记住,SQL 以基于集合的方式处理数据。现在,一个或另一个数据库实现可能碰巧以某种方式提供排序,但您永远不应该依赖它。

【讨论】:

  • 有没有可能按照聚集索引的顺序返回记录?
  • 一个很好的机会,但不能保证。涉及连接、视图、子查询等的复杂查询可能会使结果集的顺序非常不同。
  • 它有时可能会以聚集索引顺序返回,有时则不会。如果您需要特定的订单,请始终使用 order by。
  • “有机会吗?”是的,介于 0 和 100% 之间,这个范围足够大,您不应该依赖它。尽可能使用标准的 SQL 语法和行为,它极大地简化了在多个 DBMS 供应商之间移动和/或支持多个 DBMS 供应商的任务(我并不是说不要针对特定​​供应商进行优化,只是对它发疯 - 使用一些常识,不管它看起来多么不寻常:-)。
  • 我继承了如果 Oracle 返回的数据未按主键排序的软件会失败,但它从来没有这样做过。当然那是个糟糕的软件,只是提到它是因为 Oracle 看起来非常一致。
【解决方案2】:

当我进行选择时,是否始终保证我的结果将按主键排序,或者我应该使用“排序依据”来指定它?

不,目前还不能保证。

SELECT  *
FROM    table

很可能会使用TABLE SCAN,它根本不使用主键。

您可以使用提示:

SELECT  /*+ INDEX(pk_index_name) */
        *
FROM    table

,但即使在这种情况下,也不能保证排序:如果您使用Enterprise Edition,查询可能会被并行化。

这是个问题,因为ORDER BY 不能在SELECT 子句子查询中使用,而且你不能这样写:

SELECT  (
        SELECT  column
        FROM    table
        WHERE   rownum = 1
        ORDER BY
                other_column
        )
FROM    other_table

【讨论】:

  • 没问题:SELECT DISTINCT FIRST_VALUE(column) OVER (ORDER BY other_column) FROM table;
  • @Jeffrey:这是可能的,但子查询将选择所有 FIRST_VALUE 并 HASH UNIQUE 它们。如果子查询返回很多行,这将杀死所有性能。
【解决方案3】:

不,除非您使用 ORDER BY,否则无法保证订购。

获取行的顺序取决于访问方法(例如全表扫描、索引扫描)、表的物理属性、表中每行的逻辑位置以及其他因素。即使您不更改查询,这些都可能会发生变化,因此为了保证结果集中的顺序一致,ORDER BY 是必要的。

【讨论】:

    【解决方案4】:

    这取决于您的数据库,也取决于索引字段。

    例如,在我的用户表中,每个用户都有唯一的 varchar(20) 字段 - 登录名和主键 - id。

    并且“从用户中选择 *”返回按登录排序的行集。

    【讨论】:

      【解决方案5】:

      如果您需要特定的排序,请使用 ORDER BY 明确声明。

      如果表没有主键怎么办?

      【讨论】:

      • 如果表没有主键,除了数据返回的顺序还有其他问题。
      • 完全可以,但这并不能阻止人们糟糕地设计表格!
      【解决方案6】:

      如果您希望结果按特定顺序排列,请始终指定顺序

      【讨论】:

        猜你喜欢
        • 2016-08-31
        • 1970-01-01
        • 2018-02-06
        • 1970-01-01
        • 2013-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多