小编典典

对列的索引进行聚簇索引保证根据该列返回已排序的行[重复]

sql

对于这个有争议的问题,我无法得到明确的答案。 MSDN文档中提到

聚类

  • 聚集索引根据它们的键值对数据行进行 排序 并将其存储在表或视图中。这些是索引定义中包括的列。只能有一个每个表的聚集索引,因为数据行本身可以 进行排序 在只有一个订单。

  • 表中的数据行唯一 按排序 顺序存储的时间是表包含聚簇索引时。当表具有聚簇索引时,该表称为聚簇表。如果表没有聚集索引,则其数据行将存储在称为堆的无序结构中。

回答是否定的。

它是什么 ?


阅读 251

收藏
2021-04-07

共1个答案

小编典典

只是要清楚。大概是在谈论一个简单的查询,例如:

select *
from table t;

首先,如果表上的所有数据都放在一个页面上,并且表上没有其他索引,那么我很难想象这样一种情况,即结果集不是由主键排序的。但是,这是因为我认为最合理的查询计划将需要全表扫描,而不是因为SQL或SQL
Server中有任何记录或其他要求。没有显式的order by,结果集中的排序是查询计划的结果。

这成为问题的核心。当您谈论结果集的顺序时,您实际上是在谈论查询计划。而且,假设按主键排序实际上意味着您假设查询使用全表扫描。具有讽刺意味的是,人们在没有真正理解“为什么”的情况下做出了假设。此外,人们倾向于从小例子中概括(好的,这是人类智能基础的一部分)。不幸的是,他们一致地看到,对小表进行简单查询的结果集始终按主键顺序排列,并普遍适用于较大的表。在此示例中,归纳步骤不正确。

有什么可以改变的呢?临时而言,我认为如果满足以下条件,则全表扫描将按主键顺序返回数据:

  • 单线程服务器。
  • 单个文件文件组
  • 没有竞争指标
  • 没有表分区

我并不是说这总是对的。在这种情况下,这样的查询从表的开头开始使用全表扫描似乎很合理。

即使在一张小桌子上,您也会得到惊喜。考虑:

select NonPrimaryKeyColumn
from table

查询计划可能会决定使用索引table(NonPrimaryKeyColumn)而不是进行全表扫描。结果不会由主键排序(除非偶然)。我显示此示例是因为索引可以用于多种用途,而不仅仅是过滤order bywhere筛选。

如果您使用数据库的多线程实例,并且表的大小合理,则可以快速了解结果,而无需进行order by明确的排序。

最后,SQL Server有一个非常聪明的优化器。我认为order by在查询中不愿使用,因为用户认为它会自动进行排序。SQL
Server努力寻找最佳查询执行计划。如果它认识到order by由于计划的其余部分而多余,那么order by它将不会导致排序。

并且,当然,您想保证结果的顺序,这是您order by最外层查询所需要的。甚至像这样的查询:

select *
from (select top 100 t.* from t order by col1) t

不保证结果在最终结果集中排序。您确实需要执行以下操作:

select *
from (select top 100 t.* from t order by col1) t
order by col1;

以保证结果按特定顺序排列。这种行为 记录在这里

2021-04-07