包含指数:[(A)包括(B,C,D)]或[(A,B)包括(C,D)]?

时间:2016-06-20 09:34:57

标签: sql sql-server indexing

我有这样的查询:

SELECT BookID
FROM Books
WHERE IsArchived = 1 AND Rating > 60 AND CategoryID IN (1, 2, 3)

当我在SQL Server 2012中执行它时,执行计划结果告诉我

  

缺少索引:...

     

在书籍上创建非集群索引(IsArchived,Rating)INCLUDE(BookID,CategoryID)

我的问题是,我应该创建索引:

(IsArchived) INCLUDE (Rating, BookID, CategoryID)

根据给出的提示

(IsArchived, Rating) INCLUDE (BookID, CategoryID)

IMO,由于受限的列订单([Rating][IsArchived]),第二种方式不太灵活。任何建议都表示赞赏!

=======更新=======

我假设按照这样排序的列的影响级别:

[1: IsArchived]> [2: Rating]> [3: CategoryID]

因此[1 inlcude 2,3]与[1,2包括3]与[1,2,3]之间存在很大差异

2 个答案:

答案 0 :(得分:1)

设计索引时,在B_Tree中。您应该具有连接的主级别,Where子句和Order By。那么包含就是你的选择陈述。

如果您的主键仅在获得查找时,您也不需要包含BookID。但这完全取决于您服务器上的执行计划和数据量。

(IsArchived),(评级),(CategoryID)包括(BookID)

答案 1 :(得分:1)

这些索引调整更像是一种艺术形式,而不是一个确切的答案。

我对此的看法是,您实际上是根据三列

搜索数据
  1. 的isArchived
  2. 评分
  3. 类别ID
  4. 然后在SELECT语句中使用一个字段;

    • 的BookID

    从这一点来看,你知道你肯定会在包含中想要BookID,但你需要找出对于其他三个领域最适合你的方法。

    哪些字段可以帮助您最大程度地减少数据?假设您有1,000,000行数据,其中有多少有IsArchived = 1?有多少Rating > 60(这个字段是int?)?有多少CategoryID IN (1,2,3)

    对于这三个,您希望尽快减少数据量。考虑哪些会对您的数据量产生最大影响,并首先使用此数据。然后是下一个最相关的,然后是最后一个。

    当您进一步进入群集字段时,订单的影响将会降低,因此您肯定希望该字段具有最大影响力。

    修改

    根据您的编辑,只有您将了解哪些内容最适合您拥有的数据。作为没有这些信息的人,我可能会选择

    INDEX (1,2,3) INCLUDE (BookID)
    

    这将为您提供此特定查询的排序最多的数据。如果您正在测试,更新统计信息,然后测试哪个最适合您的示例,您可以随时实现一对。优化器将使用最佳的优化器,您可以检查actual execution plan以查看它正在使用的索引。