为什么 table 中的记录排序不是按照聚集索引?

Why sorting of records in table is not as per 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,'a'),(3,'d'),(5,'b'),(2,'c')

select * from trial

结果如下所示:

我的问题是:为什么结果没有按照名称列排序,因为名称列有聚簇索引?

结果是:

1 a
2 c
3 d
5 b

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

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

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

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

如果您想要特定顺序的结果,请使用 order by。 SQL 服务器有一个很好的优化器。如果它可以为查询使用索引——以避免实际排序——那么它通常会使用索引。

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

你可以强制使用聚簇索引:

SELECT * FROM TRIAL WITH (INDEX(UNQ))

你可能会得到:

和结果集:

Id  Name
1   a
5   b
2   c
3   d

但你真的不应该这样做,因为顺序仍然无法保证。如果您希望您的结果按某些列排序,请明确执行!

我会从书中复制一个片段 Exam 70-461: Querying Microsoft SQL Server 2012 在那里你可以得到一些很好的解释:

It might seem like the output is sorted by empid, but that’s not guaranteed. What could be more confusing is that if you run the query repeatedly, it seems like the result keeps being returned in the same order; but again, that’s not guaranteed. When the database engine (SQL Server in this case) processes this query, it knows that it can return the data in any order because there is no explicit instruction to return the data in a specific order. It could be that, due to optimization and other reasons, the SQL Server database engine chose to process the data in a particular way this time. There’s even some likelihood that such choices will be repeated if the physical circumstances remain the same. But there’s a big difference between what’s likely to happen due to optimization and other reasons and what’s actually guaranteed.

The database engine may—and sometimes does—change choices that can affect the order in which rows are returned, knowing that it is free to do so. Examples for such changes in choices include changes in data distribution, availability of physical structures such as indexes, and availability of resources like CPUs and memory. Also, with changes in the engine after an upgrade to a newer version of the product, or even after application of a service pack, optimization aspects may change. In turn, such changes could affect, among other things, the order of the rows in the result.

In short, this cannot be stressed enough: A query that doesn’t have an explicit instruction to return the rows in a particular order doesn’t guarantee the order of rows in the result. When you do need such a guarantee, the only way to provide it is by adding an ORDER BY clause to the query, and that’s the focus of the next section.

根据评论进行编辑:

问题是,即使您使用聚簇索引,它也可能 return 无序集。假设你有像 (1, 2, 3, 4, 5) 这样的聚集键的物理顺序。大多数时候你会得到 (1, 2, 3, 4, 5) 但在某些情况下,优化器决定进行 并行读取 并说它有 2 个并行读取并且它读取 (1, 2, 3)(4, 5)。现在可能会发生 (4, 5) 将首先被 returned,然后 (1, 2, 3) 可以被 returned。如果你没有 order by 子句引擎将不会花费它的资源来订购那个集合并且会给你 (4, 5, 1, 2, 3)。所以这就解释了为什么您应该始终确保在订购时有 order by 子句。