Sql 为什么表中的记录不按聚集索引排序?

Sql 为什么表中的记录不按聚集索引排序?,sql,sql-server,indexing,primary-key,clustered-index,Sql,Sql Server,Indexing,Primary Key,Clustered Index,我一直在为面试做准备,现在才想到这些 我已执行以下声明: create table trial ( Id int not null, Name varchar(10) ) alter table trial add constraint unq unique clustered (Name) alter table trial add constraint pk primary key nonclustered(Id) insert into trial values (1

我一直在为面试做准备,现在才想到这些

我已执行以下声明:

create table trial
(
    Id int not null,
    Name varchar(10)
)

alter table trial add constraint unq unique clustered (Name)

alter table trial add constraint pk primary key nonclustered(Id)

insert into trial values (1,'a'),(3,'d'),(5,'b'),(2,'c')

select * from trial
结果如下所示:

我的问题是:为什么结果不按名称列排序,因为名称列有聚集索引

结果是:

1 a
2 c
3 d
5 b

如何使用索引对表进行物理排序?

重复:SQL表表示无序集。SQL结果集是无序的,除非查询包含
orderby
子句

因此,如果您希望数据按顺序排列,请使用
orderby

select t.*
from trial t
order by t.name;

如果希望结果按特定顺序排列,请使用
orderby
。SQLServer有一个很好的优化器。如果它可以为查询使用索引(以避免实际的排序),那么它通常会使用索引。

在这种情况下,我确信优化器决定执行完整表扫描或非聚集索引扫描,因为它非常小。您可以包括实际执行计划,并查看以下内容:

您可以强制使用聚集索引:

SELECT * FROM TRIAL WITH (INDEX(UNQ))
你可能会得到:

和结果集:

Id  Name
1   a
5   b
2   c
3   d
但你不应该真的这样做,因为订购仍然没有保证。如果希望结果按某些列排序,请显式执行

我将从
考试70-461:查询Microsoft SQL Server 2012
一书中复制一个片段,在这里您可以得到一些很好的解释:

看起来输出是按empid排序的,但事实并非如此 放心。更令人困惑的是,如果您运行查询 反复地,结果似乎总是以相同的方式返回 秩序;但这也不能保证。当数据库引擎(SQL 服务器(在本例中)处理此查询,它知道它可以返回 因为没有明确的指令,所以数据可以按任意顺序存储 按特定顺序返回数据。可能是因为 由于优化等原因,SQLServer数据库引擎选择了 这次以特定的方式处理数据。甚至还有一些 如果发生以下情况,则重复此类选择的可能性 情况依然如此。但两者之间有很大的区别 由于优化和其他原因可能发生的情况,以及 什么是真正的保证

数据库引擎可能会,有时也可能会 是否更改可能影响行的排列顺序的选项 返回,知道这样做是自由的。这些变化的例子 在这些选择中,包括数据分布的变化、数据的可用性 物理结构,如索引和资源可用性 比如CPU和内存。此外,在发动机发生故障后 升级到产品的较新版本,甚至在应用程序之后 对于service pack,优化方面可能会发生变化。反过来,这些 除其他事项外,更改可能会影响 结果

简言之,这一点再强调也不过分:一个不符合要求的查询 具有以特定顺序返回行的显式指令 不保证结果中的行顺序。当你需要的时候 这样的保证,唯一的办法就是通过增加订单来提供 子句,这是下一节的重点

根据评论进行编辑:


问题是,即使使用聚集索引,它也可能返回无序集。假设您具有群集密钥的物理顺序,如
(1、2、3、4、5)
。大多数情况下,您会得到
(1,2,3,4,5)
,但有时优化器决定执行并行读取,并说它有2个并行读取,它读取
(1,2,3)
(4,5)
。现在可能会先返回
(4,5)
,然后才能返回
(1,2,3)
。如果您没有订购依据子句,则引擎将不会花费其资源订购该集合,并将为您提供
(4、5、1、2、3)
。因此,这就解释了为什么当您需要订购时,您应该始终确保有
orderby
子句。

标记所使用的dbms。(索引或多或少都是特定于产品的。)MS sql 2014开发者版阅读这篇关于此主题的文章。是的,我知道。。为什么表中的记录不按聚集索引排序?对不起,您无法知道表中的记录是如何排序的。您只能在查询记录时看到它们是如何返回给您的,这纯粹是SQL内部的未定问题,除非您请求指定的顺序。@Sager。问题不在于如何对表进行排序。问题是查询如何工作。如果您对页面进行了数据转储,您可能会发现数据确实是在数据页面上排序的。但是,查询不必尊重这一点。谢谢。。对于这一澄清。实际上,我知道表中记录的物理顺序总是按照聚集索引。。但我错了…@Sagar,不,你说得对。我会在回答中详细解释的。。我对这个答案非常满意。并行读取。。。对的