非聚集索引中的INCLUDE
是什么?
CREATE NONCLUSTERED INDEX [MyIndex] ON [dbo].[Individual]
(
[IndivID] ASC
)
INCLUDE ( [LastName], [FirstName])
WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PRIMARY]
我知道第一部分用于WHERE
子句,但INCLUDE
列的用途是什么?将它们“添加到非聚集索引的叶级”有什么好处?
编辑此外,如果我已经拥有IndivID
的聚集PK索引,为什么Tuning Advisor会推荐这个索引?
答案 0 :(得分:8)
INCLUDE列包含索引的关联字段。它们不用于索引,但是它们被放置在构成索引的B树的叶节点中。
实质上:索引仍然只有ON [IndivID]和[IndivID]。但是,如果您的查询只需要[IndivID],[LastName]和[FirstName]的子集,则SQL在找到它在索引中搜索的[IndivID]后不需要返回该表。
编辑:B树假设MS SQL Server。我不肯定其他实现使用相同的数据结构
Tuning Advisor(推测)::聚簇索引将整个数据行放在索引的B树的叶节点上,这占用了大量空间。如果Tuning Advisor发现您永远不会访问超过这三个字段([IndivID] + INCLUDE),它将尝试通过将其降级为非聚集索引来节省空间(并插入/更新时间)存在“重要”领域。
答案 1 :(得分:5)
INCLUDE
在索引的叶级添加这些字段。基本上bt-ree没有按那些字段排序,但是一旦索引找到了它正在查找的索引字段的行,它也会立即显示其他字段。
如果您使用电话簿类比,电话簿索引中的INCLUDED
字段(按Lastname
,Firstname
排序)将为Phone Number
和{{ 1}} - 你不能通过那些领域查找一个人,但是一旦你有了他们的名字就可以找到它们。
Address
索引已经按设计包含了所有字段,因此CLUSTERED
在INCLUDE
中无效。您也不应该在非聚集索引中CLUSTER
聚集字段,因为它已隐式存在于行键中。
我经常使用INCLUDE
字段进行聚合。例如,如果我在INCLUDE
和CalendarDate
上有索引,我可以包含CustomerID
并获取
PaidAmt
在最基本的级别,它们用于避免书签或密钥查找。
答案 2 :(得分:3)
这是在索引中作为有效负载包含的数据。它不会用于过滤,但可以返回。
例如,如果您有一个过滤年龄和返回名称的查询:
select name
from persons
where age = 42
然后,您可以为age
字段创建索引,其中包含name
字段。这样,数据库只能使用索引来运行整个查询,而不必从实际表中读取任何内容。
答案 3 :(得分:2)
来自MSDN - CREATE INDEX (Transact-SQL):
INCLUDE(列[,... n])
指定要添加到非聚簇索引的叶级别的非键列。
意思是,您可以向非聚集索引添加更多列 - 如果每次查询键列时返回多个字段,将它们添加到索引将提高性能,因为它们与它一起存储,即{{3 }}