Sql server 索引是否已包含聚集主键?

Sql server 索引是否已包含聚集主键?,sql-server,tsql,indexing,Sql Server,Tsql,Indexing,假设我有一张这样的桌子: CREATE TABLE t( [guid] [uniqueidentifier] NOT NULL, [category] [nvarchar](400) {,...other columns} ) 其中guid是我的主键,并具有聚集索引 现在,我需要一个包含category和guid的索引,因为我正在按类别汇总与t相关的其他内容,并且我希望避免包含t表本身 创建包含类别的索引就足够了吗,还是我还需要包含guid 我希望SQL Server索引直接指

假设我有一张这样的桌子:

CREATE TABLE t(
  [guid] [uniqueidentifier] NOT NULL,
  [category] [nvarchar](400)
  {,...other columns}
  )
其中
guid
是我的主键,并具有聚集索引

现在,我需要一个包含
category
guid
的索引,因为我正在按类别汇总与
t
相关的其他内容,并且我希望避免包含
t
表本身

创建包含
类别的索引就足够了吗,还是我还需要包含
guid


我希望SQL Server索引直接指向
t
中的页偏移量,而不是简单地引用
guid
主键值,这意味着我需要显式地包含PK列,以避免命中
t
。是这样吗?

事实上,您的假设是错误的-所有SQL Server非聚集索引都包含聚集键(单列或多列),并且不直接指向某个物理页面

这样,当一个页面需要拆分为两个或重新定位时,SQL Server就不必重新组织和更新大量索引项。因此,如果您在非聚集索引中搜索并找到一个值,那么您就有了聚集键,SQL Server将需要执行“书签查找”(或键查找)来检索实际的数据页(聚集索引中的叶页),以获取属于一行的整组数据

也就是说,如果您曾经遇到过依赖于键列顺序的情况,那么您可能仍然需要专门在
(guid,category)
上创建索引,当然,在这种情况下,SQL Server足够聪明,可以发现集群键列已经在索引中,并且不会再添加它


聚类键列包含在每个非聚类索引中这一事实是聚类键应该是窄的、静态的和唯一的另一个重要原因。使它们太宽(超过8字节)肯定会导致膨胀和减速。

与marc_的答案略有不同

(类别,guid)上的覆盖索引的guid排序与主键排序不同。因此,guid可能在索引中出现两次,因为它位于键列列表和指向聚集索引的指针中

如果包含guid(作为非键列),SQL Server将不会再次添加它


我现在无法测试关键列,但我已经在SQL Server 2005上验证了包含一个。

谢谢Marc!我以为我在解释执行计划时会发疯。有道理的是,索引不应该与页面指针混在一起,即使有避免书签查找的微小性能优势。关于订购也很有道理。