为什么PK被列为其索引中包含列?

时间:2013-02-14 14:18:36

标签: sql-server-2008 primary-key indexing

我一直在使用Adventureworks2008R2学习索引,并被告知要运行此查询。

SELECT s.name AS SchemaName,
       OBJECT_NAME(i.object_id) AS TableOrViewName,
       i.name AS IndexName,
       c.name AS ColumnName
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic
  ON i.object_id = ic.object_id 
INNER JOIN sys.columns AS c
  ON ic.object_id = c.object_id
AND ic.column_id = c.column_id 
INNER JOIN sys.objects AS o
  ON i.object_id = o.object_id
INNER JOIN sys.schemas AS s
  ON o.schema_id = s.schema_id 
WHERE ic.is_included_column <> 0
  AND s.name <> 'sys'
ORDER BY SchemaName, TableOrViewName, i.index_id, ColumnName;

输出如下:

    SchemaName     TableorViewName   IndexName                          ColumnName
1   Production     Productreview     PK_ProductReview_ProductReviewID   Comments
2   Production     Productreview     IX_ ProductReview_ProductId_Name   Comments

我理解为什么它列出了IX_ ProductReview_ProductId_Name但却无法说明它为什么显示PK_ProductReview_ProductReviewID。

注释说明“根据定义,聚集索引中的所有列都已包含在内。” 在这种情况下,为什么只显示“注释”列,为什么不列出所有PK?

我怀疑自己是愚蠢的,但是。 。 。 TIA

- 修改 它认为表中具有包含列的非聚集索引的所有PK都显示具有相同的包含列。 这就是“如何”回答,但我仍然喜欢“为什么”回答。

1 个答案:

答案 0 :(得分:0)

这些加入条件中至少有一个似乎不够。 sys.indexessys.index_columns都可以为同一object_id定义多个索引。

尝试:

FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic
  ON i.object_id = ic.object_id AND
    i.index_id = ic.index_id

换句话说,我认为其中一行是由这种错误连接产生的幻像。你看到了它,因为它恰好是同一个表上的另一个索引。


顺便说一下,过滤掉系统对象(通常)的更好方法是在WHERE子句中包含OBJECTPROPERTY(object_id,N'IsMSShipped') = 0,而不是查询对象所属的模式。