Sql server 2008 sql server如何对数据进行排序?

Sql server 2008 sql server如何对数据进行排序?,sql-server-2008,select,sql-order-by,Sql Server 2008,Select,Sql Order By,我想知道sql server是如何对数据进行排序的。 我注意到,如果我有一个不包含列Id的表,并且您通过sql server选择了无顺序数据,则不会自动对主列进行排序 有人知道sql server按照什么规则对其数据进行排序吗?如果不明确指定ORDER BY子句,则无法保证结果的排序顺序。它甚至不能保证基于聚集索引 您可以在中看到这方面的一个例子。虽然很想知道如何解释您经常看到相同的顺序,但我想指出,依赖底层数据库引擎的特定实现所导致的隐式顺序从来都不是一个好主意。换句话说,知道原因很好,但你永

我想知道sql server是如何对数据进行排序的。 我注意到,如果我有一个不包含列Id的表,并且您通过sql server选择了无顺序数据,则不会自动对主列进行排序


有人知道sql server按照什么规则对其数据进行排序吗?

如果不明确指定ORDER BY子句,则无法保证结果的排序顺序。它甚至不能保证基于聚集索引


您可以在中看到这方面的一个例子。

虽然很想知道如何解释您经常看到相同的顺序,但我想指出,依赖底层数据库引擎的特定实现所导致的隐式顺序从来都不是一个好主意。换句话说,知道原因很好,但你永远不应该依赖它。对于MS SQL,唯一可靠地按特定顺序传递行的是显式order BY子句

不同的RDMB不仅表现不同,而且由于更新补丁,某个特定实例的表现也可能不同。不仅如此,甚至RDBMS软件的状态也可能产生影响:热数据库的行为不同于冷数据库,小表的行为不同于大表

即使您有实现的背景信息,例如:有一个聚集索引,因此很可能会按聚集索引的顺序返回数据,总有一种可能是您不知道的另一种机制导致行以不同的顺序返回ex1:如果另一个会话刚刚以显式顺序执行了完整的表扫描,则resultset可能已被缓存;随后的完全扫描将尝试从缓存返回行;ex2:可能通过对数据排序来实现GROUP BY,从而影响行的返回顺序;ex3:如果所选列都在已缓存在内存中的辅助索引中,则引擎可能会扫描辅助索引而不是表,很可能会按辅助索引的顺序返回行

这里有一个非常简单的测试,说明了我的一些观点

首先,启动我正在使用的SQL server 2008。创建此表:

create table test_order (
    id int not null identity(1,1) primary key
,   name varchar(10) not null 
)
检查该表,并见证创建了群集索引以支持id列上的主键。例如,在SQLServerManagementStudio中,您可以使用树视图并导航到表下的indexes文件夹。在这里,您应该看到一个索引,其名称如下:PK__test_ord__3213;e83f03317e3d

插入包含此语句的第一行:

insert into test_order(name)
select RAND()
重复此语句16次以插入更多行:

insert into test_order(name)
select RAND()
from   test_order
您现在应该有65536行:

select COUNT(*) 
from   test_order
现在,选择所有行而不使用order by:

select *
from   test_order
最有可能的是,结果将按主键的顺序返回,尽管没有保证。下面是我得到的结果,它确实是按主键的顺序排列的:

#      id    name
1      1     0.605831
2      2     0.517251
3      3     0.52326
.      .     .......
65536  65536 0.902214
不是列,而是行在结果中的顺序位置

现在,在“名称”列上创建二级索引:

选择所有行,但仅检索名称列:

结果很可能会按二级索引idx_名称的顺序返回,因为查询只能通过扫描索引i.o.w来解决。idx_名称是一个覆盖索引。这是我得到的结果,确实是按名字的顺序排列的

现在,再次选择所有列和所有行:

select * 
from test_order
以下是我得到的结果:

#      id    name
1      17    0.0185732
2      18    0.0185732
3      19    0.0185732
...    ..    .........
正如您所看到的,与我们第一次运行此查询时完全不同。看起来行是按二级索引排序的,但我没有解释为什么会这样


无论如何,底线是——不要依赖于隐含的顺序。您可以考虑解释为什么可以观察到特定的顺序,但即使如此,您也不能像后一种情况那样,在不熟悉实现和运行时状态的情况下总是预测它。

因为SQL基于集合理论,集合不保证任何顺序,因此如果您不明确指定特定的顺序,订单无法保证。

我有过类似的经历,SQL Server返回的结果排序与我预期的不同。我发现,如果您在select语句中指定一个表提示,并给出聚集索引的名称,则可以按您想要的方式对结果进行排序:

select * from test_order WITH (INDEX([ClusteredIndexName]))

值得一提的是,表上任何具有聚集主键的二级索引都会在索引的隐藏字段中保存主键的副本。所以在我们的例子中,它确实可以用来获取id和value。谢谢你们的回答,我不知道查询优化程序可以根据索引是否已经在RAM缓存中来选择索引。
select * 
from test_order
#      id    name
1      17    0.0185732
2      18    0.0185732
3      19    0.0185732
...    ..    .........
select * from test_order WITH (INDEX([ClusteredIndexName]))