主键排序

时间:2009-07-10 15:43:53

标签: sql sql-server indexing

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

7 个答案:

答案 0 :(得分:12)

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

如果没有ORDER BY子句,则不保证SQL中的数据具有顺序。当您需要按特定顺序排列数据时,应始终指定ORDER BY子句。如果表已按此方式排序,优化器将不会执行任何额外的工作,因此将其存储在那里没有任何害处。

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

修改

如果在排序时与不排序时产生性能影响,则可能会对没有索引(群集或其他)的列(或列集)进行排序。鉴于它是一个时间序列,您可能会根据时间进行排序,但聚集索引位于主要bigint上。 SQL Server不知道两者都以相同的方式增加,所以它必须采取一切措施。

如果时间列和主键列是按顺序相关的(当且仅当另一个增加或保持不变时,才会增加),而是按主键排序。如果它们不相关,请将聚簇索引从主键移动到您要排序的任何列。

答案 1 :(得分:2)

没有显式的ORDER BY,没有默认的排序顺序。一个非常常见的问题。因此,有一个罐头答案:

Without ORDER BY, there is no default sort order.

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

答案 2 :(得分:1)

默认情况下,表格不是“群集”,即由PK组织。您可以选择指定它。所以默认是“HEAP”(没有特别的顺序),你正在寻找的选项是“CLUSTERED”(SQL Server,在Oracle中称为IOT)。

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

早期的海报是正确的,SQL(及其理论基础)专门将select定义为无序的set / tuple。

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

在SQL Server中:不,通过群集密钥 - 默认为主键,但不必相同。

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

不确定其他数据库系统。

马克

答案 5 :(得分:0)

这可能是特定于实现的,但MySQL似乎默认按主键排序。但是,如果您需要保证以某种方式订购行,则应添加ORDER BY。

答案 6 :(得分:0)

几乎每次它都会按表Identity排序。它按聚集索引排序,并且可能不总是按标识排序,但我从未看到它在选择*时没有按标识ID排序。不指定订单的原因是什么?我不明白为什么它会导致性能上的差异。