1

我一直在研究使用 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。

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

我怀疑我真的很愚蠢,但是。. . TIA

--Edit 似乎表上具有包含列的非聚集索引的所有 PK 都显示为具有相同的包含列。那是回答的“如何”,但我仍然希望回答“为什么”。

4

1 回答 1

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

换句话说,我认为其中一行是由这个不正确的连接产生的幻象。您看到它是因为它恰好是同一张表上的另一个索引。


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

于 2013-02-14T14:39:25.043 回答