sql-server-2008 - sql server 如何对你的数据进行排序?

标签 sql-server-2008 select sql-order-by

我想知道 sql server 如何对其数据进行排序。
我注意到,如果我有一个不包含“Id”列的表,并且您选择没有“ORDER BY”的数据,sql server 不会自动对主列进行排序。

有谁知道sql server遵循什么规则来对其数据进行排序?

最佳答案

虽然想知道如何解释您经常看到相同的顺序是件好事,但我想指出,依赖由底层数据库引擎的特定实现引起的隐式顺序绝不是一个好主意。换句话说,很高兴知道为什么,但你永远不应该依赖它。对于 MS SQL,唯一能够以特定顺序可靠地传送行的是显式 ORDER BY条款。

不仅不同的 RDMBS-es 行为不同,一个特定的实例可能由于更新(补丁)而行为不同。不仅如此,甚至 RDBMS 软件的状态也可能产生影响:“暖”数据库的行为与“冷”数据库的行为不同,小表的行为与大表的行为不同。

即使你有关于实现的背景信息(例如:“有一个聚集索引,因此数据很可能会按聚集索引的顺序返回”),也总是有可能你没有其他机制不知道这会导致以不同的顺序返回行(例如:“如果另一个 session 刚刚使用显式 ORDER BY 进行了全表扫描,结果集可能已被缓存;随后的全扫描将尝试返回行从缓存中"; ex2: "a GROUP BY 可以通过对数据进行排序来实现,从而影响行返回的顺序"; ex3: "如果所选列都在已经缓存在内存中的二级索引中,引擎可能会扫描二级索引而不是表,最有可能按二级索引的顺序返回行”)。

这是一个非常简单的测试,它说明了我的一些观点。

首先,启动 SQL 服务器(我使用的是 2008)。创建此表:

create table test_order (
    id int not null identity(1,1) primary key
,   name varchar(10) not null 
)

检查表并证明创建了一个聚集索引来支持 primary keyid柱子。例如,在 sql server management studio 中,您可以使用树 View 并导航到表下方的索引文件夹。在那里您应该看到一个索引,其名称类似于:PK__test_ord__3213E83F03317E3D (Clustered)
使用以下语句插入第一行:
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 的情况下选择所有行:
select *
from   test_order

最有可能的是,结果将按主键的顺序返回(尽管不能保证)。这是我得到的结果(确实是按主键的顺序):
#      id    name
1      1     0.605831
2      2     0.517251
3      3     0.52326
.      .     .......
65536  65536 0.902214

(# 不是列而是结果中行的序数位置)

现在,在 name 上创建二级索引柱子:
create index idx_name on test_order(name)

选择所有行,但只检索 name柱子:
select name
from   test_order

结果很可能会按二级索引 idx_name 的顺序返回,因为查询可以通过只扫描索引来解析(i.o.w. idx_name 是一个覆盖索引)。这是我得到的结果,确实是按 name 的顺序排列的.
#      name
1      0.0185732
2      0.0185732
.      .........
65536  0.981894

现在,再次选择所有列和所有行:
select * 
from test_order

这是我得到的结果:
#      id    name
1      17    0.0185732
2      18    0.0185732
3      19    0.0185732
...    ..    .........

如您所见,与我们第一次运行此查询时完全不同。 (看起来行是按二级索引排序的,但我没有解释为什么会这样)。

无论如何,底线是 - 不要依赖隐式顺序。您可以考虑解释为什么可以观察到特定顺序,但即便如此,如果没有对实现和运行时状态的深入了解,您也无法始终预测它(如后一种情况)。

关于sql-server-2008 - sql server 如何对你的数据进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2040724/

相关文章:

PHP:从 MySQL 中的内爆数组中选择一个值

MySQL ORDER BY 另一个表的列名

mysql自定义排序依据与混合数据类型

c - 即使您的网络连接断开,套接字是否仍然可写?

sql - 没有反向的查询结果

具有多个 ROW_NUMBER 或 RANK 的 SQL

sql-server-2008 - 程序中表值参数中的标识列,如何定义DataTable

mysql - 选择除 A 或 B 之外的记录

mysql - MYSQL 计数结果的自定义排序顺序?

sql-server-2008 - 无法将值 NULL 插入到列 '' 中,表列不允许空值。 INSERT 失败。无法执行以下 SQL block