【问题标题】:Primary Key Sorting主键排序
【发布时间】:2010-11-09 18:25:37
【问题描述】:

一个表本质上是按它的主键排序的吗?如果我在 BigInt 标识列上有一个带有主键的表,我可以相信查询将始终返回按键排序的数据,还是我明确需要添加“ORDER BY”。性能差异很大。

【问题讨论】:

标签: sql sql-server indexing


【解决方案1】:

数据通过聚集索引物理存储,通常是主键但不一定是。

如果没有 ORDER BY 子句,则不能保证 SQL 中的数据具有顺序。当您需要数据按特定顺序排列时,您应该始终指定 ORDER BY 子句。如果表已经按这种方式排序,优化器不会做任何额外的工作,所以把它放在那里并没有什么坏处。

如果没有 ORDER BY 子句,RDBMS 可能会在等待从磁盘读取记录时返回与您的查询匹配的缓存页面。在这种情况下,即使表上有索引,数据也可能不会按照索引的顺序出现。 (注意这只是一个例子——我不知道甚至不认为现实世界的 RDBMS 会这样做,但对于 SQL 实现来说这是可以接受的行为。)

编辑

如果您在排序和不排序时对性能有影响,那么您可能正在对没有索引(聚集或其他)的列(或一组列)进行排序。鉴于它是一个时间序列,您可能会根据时间进行排序,但聚集索引位于主 bigint 上。 SQL Server 不知道两者的增长方式相同,因此它必须采取一切措施。

如果时间列和主键列是按顺序相关的(当且仅当另一个增加或保持不变时,一个增加),而是按主键排序。如果它们不以这种方式关联,请将聚集索引从主键移动到您排序所依据的任何列。

【讨论】:

  • 第一段应该说“数据是由聚集索引物理存储的......”。 Welbog 所说的所有其他内容都适用——仅仅因为它按顺序物理存储 [在每一页内] 并不意味着您会按该顺序取回它。物理磁盘碎片也可能对此产生影响。
  • @Philip Kelley:更改以反映您更好的措辞。谢谢。
  • 我实际上是在主键(即 BigInt)上进行排序。数据已按顺序(按日期)插入。
  • 主键是聚集索引吗?
  • 主键是集群的,键是ID(BigInt)字段。
【解决方案2】:

如果没有明确的 ORDER BY,就没有默认的排序顺序。一个很常见的问题。因此,有一个固定的答案:

Without ORDER BY, there is no default sort order.

您能否详细说明为什么“性能差异很大。”?

【讨论】:

  • 数据是时间序列,查询正在拉回数月的数据。如果没有 Order By,存储过程能够在几秒钟内开始返回行。使用 Order By 最多可以在第一行返回之前一分钟。
  • 你可以试试 OPTION(FAST 1) msdn.microsoft.com/en-us/library/ms181714.aspx
【解决方案3】:

默认情况下,表不是 'clustered' ,即按 PK 组织。您确实可以选择这样指定它。所以默认是“HEAP”(没有特别的顺序),而您正在寻找的选项是“CLUSTERED”(SQL Server,在 Oracle 中称为 IOT)。

  • 一张表只能有一个 CLUSTERED(有意义)
  • 在 DDL 上使用 PRIMARY KEY CLUSTERED 语法
  • 仍然需要在您的 SELECTS 上发出按 PK 排序,它被聚集的事实将导致查询运行得更快,因为优化器计划将知道它不需要对聚集索引进行排序

较早的海报是正确的,SQL(及其理论基础)专门将选择定义为无序集/元组。

SQL 通常会尝试停留在逻辑领域,而不是对数据的物理组织/位置等做出假设。 CLUSTERED 选项允许我们在实际的现实生活中这样做。

【讨论】:

    【解决方案4】:

    您必须申请ORDER BY 才能保证订单。如果您注意到性能差异,那么很可能您的数据没有在没有ORDER BY 的情况下进行排序 - 否则 SQL-Server 一定表现不佳,因为它没有意识到数据已经排序。在已排序的数据上添加 ORDER BY 不会导致性能损失,因为 RDBMS 应该足够智能以实现数据的顺序。

    【讨论】:

      【解决方案5】:

      在 SQL Server 中:不,它是 集群键 - 默认为主键,但不必相同。

      主键的主要功能是唯一标识表中的每一行 - 但它本身并不意味着任何(物理)排序。

      不确定其他数据库系统。

      马克

      【讨论】:

        【解决方案6】:

        这可能是特定于实现的,但默认情况下 MySQL 似乎按主键排序。但是,任何时候如果您需要保证行将以某种方式排序,您应该添加 ORDER BY。

        【讨论】:

        • 仅当主键也是 CLUSTERING KEY 时 - 默认情况下,但不一定是......
        【解决方案7】:

        几乎每次它都会按表身份排序。它确实按聚集索引排序,并且可能并不总是按标识排序,但我从未见过它在选择 *.不指定订单的原因是什么?我不明白为什么它会导致性能差异。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-24
          • 2011-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-08-04
          • 1970-01-01
          相关资源
          最近更新 更多