sql-server - 为什么 SQL Server 在 "select *"操作中使用非聚集索引而不是聚集 PK?

标签 sql-server clustered-index sql-execution-plan non-clustered-index

我有一个非常简单的表,用于存储人们的头衔(“先生”、“女士”等)。这是我正在做的事情的简要版本(在本示例中使用临时表,但结果是相同的):

create table #titles (
    t_id    tinyint     not null    identity(1, 1),
    title   varchar(20) not null,

    constraint pk_titles primary key clustered (t_id),
    constraint ux_titles unique nonclustered (title)
)
go

insert #titles values ('Mr')
insert #titles values ('Mrs')
insert #titles values ('Miss')

select * from #titles

drop table #titles

请注意,表的主键是聚集的(为了示例而明确),并且标题列存在非聚集唯一性约束。

这是选择操作的结果:

t_id title
---- --------------------
3    Miss
1    Mr
2    Mrs

查看执行计划,SQL 使用非聚集索引而不是聚集主键。我猜这解释了为什么结果按这个顺序返回,但我不知道它为什么这样做。

有什么想法吗?更重要的是,有什么办法可以阻止这种行为吗?我希望行按照插入的顺序返回。

谢谢!

最佳答案

如果您想要顺序,则需要指定显式的ORDER BY - 其他任何内容都不会产生顺序(它的“顺序”是随机的并且可能会改变)。 SQL Server 中没有隐含的排序——没有任何隐含的排序。如果您需要订购 - 请使用 ORDER BY 表示。

SQL Server 可能使用非聚集索引(如果可以的话 - 如果该索引包含查询要求的所有列),因为它较小 - 通常只有索引列和聚集键(再次强调:一列或多列)。另一方面,聚集索引是整个数据(在叶级别),因此可能需要读取更多数据才能得到答案(当然不是在这个过于简化的示例中 - 但在现实世界)。

关于sql-server - 为什么 SQL Server 在 "select *"操作中使用非聚集索引而不是聚集 PK?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6936891/

相关文章:

mysql - 有没有办法强制 MySQL 执行顺序?

sql-server - WHERE 子句中的列顺序重要吗?

sql - 在SQL中,什么情况下我们要对表中的一个字段进行索引,或者同时对表中的2个字段进行索引?

sql-server - 两列上的聚集索引

mysql - 在 SQL 中基于聚簇索引和非聚簇索引优化查询?

oracle - 解释计划和执行计划的区别

sql - RID 查找 - 逻辑搜索

sql - 表的大小会影响 SQL Server 中插入查询的性能吗?

sql-server - 在为数据库的文件/文件组分配空间后,如何分配磁盘空间

SQL Server : Arithmetic overflow error converting expression to data type int