我有这样的查询:
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]之间存在很大差异
答案 0 :(得分:1)
设计索引时,在B_Tree中。您应该具有连接的主级别,Where子句和Order By。那么包含就是你的选择陈述。
如果您的主键仅在获得查找时,您也不需要包含BookID。但这完全取决于您服务器上的执行计划和数据量。
(IsArchived),(评级),(CategoryID)包括(BookID)
答案 1 :(得分:1)
这些索引调整更像是一种艺术形式,而不是一个确切的答案。
我对此的看法是,您实际上是根据三列
搜索数据然后在SELECT语句中使用一个字段;
从这一点来看,你知道你肯定会在包含中想要BookID
,但你需要找出对于其他三个领域最适合你的方法。
哪些字段可以帮助您最大程度地减少数据?假设您有1,000,000行数据,其中有多少有IsArchived = 1
?有多少Rating > 60
(这个字段是int?)?有多少CategoryID IN (1,2,3)
?
对于这三个,您希望尽快减少数据量。考虑哪些会对您的数据量产生最大影响,并首先使用此数据。然后是下一个最相关的,然后是最后一个。
当您进一步进入群集字段时,订单的影响将会降低,因此您肯定希望该字段具有最大影响力。
修改强>
根据您的编辑,只有您将了解哪些内容最适合您拥有的数据。作为没有这些信息的人,我可能会选择
INDEX (1,2,3) INCLUDE (BookID)
这将为您提供此特定查询的排序最多的数据。如果您正在测试,更新统计信息,然后测试哪个最适合您的示例,您可以随时实现一对。优化器将使用最佳的优化器,您可以检查actual execution plan
以查看它正在使用的索引。