这是使用include中的所有列创建索引的不良做法吗?

时间:2012-12-27 06:08:45

标签: sql sql-server sql-server-2008 tsql indexing

我有一个表,我在字段中创建非聚集索引,这些索引经常用于搜索where子句。我正在使用include子句创建索引并将所有字段放在其中。

例如:

Create NonClustered Index IX_DocumentDate on Documents
(
    DocumentDate     
)
Include(
    JurisdictionID,
    JudgementTypeID,
    IDate,
    EfileDate,
    UserID,
    RecordingDateTime,
    ApprovedBy,
    ACEfileBankAccountID,
    LastStatusChangedDateTime,
    ACEfileCreditCardID,
    EfiledByUserID,
    ITypeID,
    IGroupID,
    InstrumentID,
    OldInstrumentID,
    [CreatedByJurisdictionID],
    CreatedByAccountID,
    [DocumentStatusID]      
      ,[Remarks]
      ,[InternalNotes]
      ,[ParentDocumentID]
      ,[FilingNumber]
      ,[StampData]      
      ,[Receipt]
      ,[ReceiptNo]
      ,[IsReEfiled]      
      ,[ImportedFromInstrumentID]
)

与仅创建索引相反。这些字段全部用于Select。只是想知道我做错了吗?当我这样做时,我获得了巨大的性能奖励。如果这没关系,那么为什么Microsoft不将它用作默认选项并在include中包含表的所有字段?

3 个答案:

答案 0 :(得分:5)

是。一般来说,在SQL中,拥有一个模式总是很糟糕 - 一个LOT取决于使用情况,而且会有所不同。

在上述情况下,这可能是也可能不是明智的,也不是必需的或有益的。不要忘记付出代价 - 光盘大小(= IO和更多RAM使用率)以及更新和插入速度(更慢)。

通常,应谨慎使用INCLUDE。从没有开始,然后在有问题的地方使用它,它会有所帮助。

答案 1 :(得分:3)

您将整个表存储两次,一次存储在索引中,一次存储在主表中。这通常被视为浪费空间。它还降低了指数的效率;如果您将自己限制为不包含列,或仅包含少量列,则需要读取更多数据。在索引中包含主文档ID列可能是明智的(尽管不清楚哪个列是主文档ID),但是您包含的大多数列对于索引来说显然是多余的。

因此,它不是默认行为的原因是因为它没有包含列的索引那么高效。因此,在您需要之前,请不要在索引中包含任何列,并且可以衡量它是否会提高性能。

答案 2 :(得分:0)

您可以为一列尝试聚簇索引,可以使用主键,然后检查性能。您可以将聚簇索引的性能与索引与所有列进行比较。 最佳实践表明,您应该根据要求拥有最小索引。