为什么 SQL Server 在“select *”操作中使用非聚集索引而不是聚集 PK?

2023-12-28

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

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 使用非聚集索引而不是聚集主键。我猜这解释了为什么结果按这个顺序返回,但我不知道它为什么这样做。

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

Thanks!


如果你想要顺序,你需要指定一个明确的ORDER BY- 其他任何事情都可以not产生一个订单(它的“订单”是随机的并且可能会改变)。 SQL Server 中没有隐含的排序 - 没有任何隐含的排序。如果您需要订购 - 请这样说ORDER BY.

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 SQL Server 在“select *”操作中使用非聚集索引而不是聚集 PK? 的相关文章

  • 在 SQL Server 中通过标准差消除异常值

    我试图通过标准差消除 SQL Server 2008 中的异常值 我只想要特定列中包含该列平均值的 1 标准差范围内的值的记录 我怎样才能做到这一点 如果您假设事件呈钟形曲线分布 则只有 68 的值与平均值相差 1 个标准差以内 95 的值
  • 如何使用sql脚本更改列的属性

    如何使用 sql 脚本更改列的属性 这是我尝试过但出现错误的方法 ALTER TABLE dbo tblBiometricPattern COLUMN BiometricPatternID TINYINT NOT NULL IDENTITY
  • 在 Sql STUFF 命令中将最后一项的逗号分隔符替换为“and”

    如果我查询的输出是英国 美国 印度 是否可以像英国 美国那样显示查询结果and India 这是我的查询 Select stuff Select Distinct Country as text from tbl Country where
  • 批量插入不适用于 NULL 数据

    当我从 CSV 文件将批量数据插入到表中时 它不起作用 显示错误 第 2 行第 9 列的批量加载数据转换错误 类型不匹配或指定代码页的字符无效 csv 文件中的第 9 列值为空 我该如何处理这个问题 根据这些信息 我认为目标表的特定字段被定
  • Sql Server 的夏令时

    我们正在使用一个以 C Unix 格式存储日期的旧应用程序 C 时间基本上是自 1970 年 1 月 1 日以来的秒数 日期以整数形式存储在 SQL Server 数据库中 我正在为使用这些日期的报告编写视图 到目前为止 我正在使用以下命令
  • 实体框架中的批量插入

    我使用批量插入插入大量记录 例如 20K 当我仅插入一个实体时 它会正常工作 但是 当我用来插入多个实体 例如一对多 时 它将仅插入父实体 而不会插入子实体 我的实体和代码 Customer cs public class Customer
  • SQL Server Like 查询不区分大小写

    Query SELECT from Table 2 WHERE name like Joe Output 1 100 Joe 2 200 JOE 3 300 jOE 4 400 joe 为什么不区分大小写 Problem 查询不区分大小写
  • 合并sql中的列

    我正在使用 SQL Server 2017 有一个存储过程 其中我有一个带有连接的简单选择 例如 SELECT p legacyKey AS JobNumber p Name AS JobName G Label AS DesignStat
  • SQL 查询将文本数据存储在 Varbinary(max) 中

    有没有办法让 varbinary 在 SQL Server 中接受文本数据 这是我的情况 我有相当大量的 XML 我计划以 压缩 格式存储它们 这意味着 Varbinary 但是 当我进行调试时 我希望能够翻转配置开关并以纯文本形式存储 以
  • 当我使用可变参数而不是常量参数时,为什么我的内联表 UDF 慢得多?

    我有一个表值内联 UDF 我想过滤该 UDF 的结果以获得一个特定值 当我使用常量参数指定过滤器时 一切都很好 并且性能几乎是瞬时的 当我使用可变参数指定过滤器时 它会花费明显更大的时间块 大约是逻辑读取的 500 倍和持续时间的 20 倍
  • SQL Server 2012:有条件地增加计数器用户 ROW_NUMBER()

    我正在尝试申请ROW NUMBER 根据特定条件增加计数器 我的数据如下所示 目标计数器是Prep column id DSR PrepIndicator Prep 1662835 1 1 1 1662835 14 2 2 1662835
  • SQL Server 2008 错误 233

    我正在使用以下 sql 脚本在 SQL Server 2008 中创建新登录名 CREATE LOGIN xyz WITH PASSWORD xyz DEFAULT DATABASE master DEFAULT LANGUAGE us e
  • 分组和切换列和行

    我不知道这是否会被正式称为枢轴 但我想要的结果是这样的 Alex Charley Liza 213 345 1 23 111 5 42 52 2 323 5 23 1 324 5 我的输入数据采用这种形式 Apt Name
  • 从字符串中删除某些字符

    我正在尝试删除某些字符 目前我的输出如下cityname district但我想删除cityname SELECT Ort FROM dbo tblOrtsteileGeo WHERE GKZ 06440004 Output B dinge
  • 在 C# 中执行基于存储过程的查询后,如何重新使用 CommandText 的 SqlCommand 对象?

    我有一个示例代码 aCommand CommandType CommandType StoredProcedure aCommand Parameters AddWithValue book id bookID aCommand Param
  • 如何拥有引用另一个表的检查约束?

    我在 SQL Server 2008 数据库中有以下表 tblItem 其中有一个ItemID field 好项目 它还有一个 ItemID 字段 并且有一个指向 tblItem 的外键 tblBadItem 它也有一个 ItemID 字段
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • 没有提示指令的直连接中表的顺序是否会影响性能?

    所有基于 SQL 的 RDBMS 10 年前的版本 直接连接查询 没有提示指令 中的表顺序是否会对最佳性能和内存管理产生影响 听说最后一个join应该是最大的表 您的数据库的查询优化器如何处理这种情况 回答你的问题 是的 表的顺序在连接中有
  • 在 SQL Server 2005 中,len() 和 datalength() 有什么区别?

    SQL Server 2005 中的 len 和 datalength 有什么区别 DATALEN 将返回用于存储值的字节数 http msdn microsoft com en us library ms173486 SQL 90 asp
  • 如何使用一个命令删除 SQL 数据库中的所有索引?

    那么 如何通过一条命令删除 SQL 数据库中的所有索引呢 我有这个命令可以获取所有 20 个左右的 drop 语句 但是如何从这个 结果集 运行所有这些 drop 语句呢 select from vw drop idnex 给我相同列表的另

随机推荐